在pandas中,如果需要查看column的类型,一般使用
df.dtypes
方法,它将返回每个列的数据类型,但是如果涉及到多个类型,该方法只能返回一个类型,比如
frame = pd.DataFrame({'Yes': [41, None, 'str', 70, 21.3], 'No': [131, 2, None, 1, 3]})
print(frame.dtypes)
输出为
Yes object
No float64
dtype: object
可以看到,Yes被标注为object,No被标注为float。我们发现一列中只要包含字符串,会被标记为object类,而包含nan(空值),其他元素为int的列会被标注为float。
一般而言,一列中一般只包含一种数据类型。但实践中,有时dataFrame包含的表格可能出错,或者处于需要包含多种数据类型。如果我们想要观察dataFrame中的所有类型的分布情况,就需要自己动手啦~
我们写了一个简单的函数,输入的是dataFrame,输出俩列表。第一个列表是我们要的所有列包含的所有数据类型,按列进行统计;第二个列表包含所有含多个数据类型的列(不包括nan),输出的结构为
[(column名,{数据类型列表})] 和
[所有含多个数据类型的列(不包括nan)]
上代码(doge)
def check_df_types(frame) ->(list,list):
assert len(frame.index) != 0 #要求df不为空
report_list = []
multiple_type_list = []
null_df = frame.isnull().sum()
还是在函数内部,判断类型
columns = frame.columns
for column in columns:
type_dict = {'int':0, 'float':0, 'None':0, 'str':0, 'unkown':0}
for item in frame[column]: #类型判断与计数
if isinstance(item,int):
type_dict['int'] = type_dict['int'] + 1
elif item is None: # series是object的时候None是None,数字的None是float
continue
elif isinstance(item,float): # df中None属于float.Python也是的,大概
type_dict['float'] = type_dict['float'] + 1
elif isinstance(item,str): # series中只要有,就是object
type_dict['str'] = type_dict['str'] + 1
else:
type_dict['unkown'] = type_dict['unkown'] + 1
由于nan是算float的,数据类型为float要在float里面减掉nan,数据类型是object的话 ,由于nan被记成float,要加上去(doge)
nan_count = null_df[column]
type_dict['None'] = type_dict['None'] + nan_count
if str(frame[column].dtype) == 'float64': # 可能出问题,但int里面有None会转成float
type_dict['float'] = type_dict['float'] - nan_count
report_list.append((column,type_dict))
count = 0
for key in type_dict:
if type_dict[key] != 0 and key != 'None':
count += 1
if count > 1:
multiple_type_list.append(column)
print(column + ' is: ' +str(type_dict))
return report_list, multiple_type_list
最后调用函数,over~
l,l2 = check_df_types(frame)
print(l2)
结果正是我们想要的,拿到了一列中所有的数据类型,打印了含多种数据类型的有潜在异常的列。
对比一下
frame = pd.DataFrame({'Yes': [41, None, 'str', 70, 21.3], 'No': [131, 2, None, 1, 3]})
print(frame.dtypes)
可以看到,No那一列虽然是int,但里面有nan,数据类型在创建的时候就已经被pandas被改成float了,虽然我们遍历了整个dataFrame,但这个int没有被catch到(doge),如果要求不高就…这样吧。
申明:虽然我挺菜的,但代码是我自己写的,加引用哈~,喜欢的话点个免费的赞吧(白嫖怪震怒)
—————————————-分隔线———————————————
对于之前的问题,我们有一个解决方法:不分int和float,叫它num就完事了(doge)
加一行代码,由于我懒得改函数了,就加在外面吧
for d in l:
d = d[1]
d['num'] = d['int'] + d['float']
del d['int']
del d['float']
print(d)