如何从数据框架Pandas中删除具有错误数据类型的行



我正在分析来自工业控制系统的数据,该系统以1秒的间隔将传感器数据记录到CSV文件。我们每周做一次分析,所以CSV文件很大(49列x ~600k行)。有时(可能是由于字段停电),CSV文件有损坏的行。我们得到列数正确但数据类型错误的行。下面是一个虚拟DF,以较小的规模说明了这个问题:

mydict = {'colFloat': [1.5, 2.3, 'TRUE', 'FALSE', 3.5, 7.8], 'colBool': ['FALSE', 'TRUE', 3.2, 1.1, 'TRUE', 'TRUE'], 'colInt': [2, 2, 3.7, 9.9, 1, 4]}
df = pd.DataFrame(data = mydict)

在这个例子中,'colFloat'应该是dtype float64, 'colBool'应该是dtype bool, 'colInt'应该是dtype int64,但是当然中间的两行错误导致所有三列都是object类型。后来,当我尝试做组比和集成传感器读数(例如来自'colFloat')时,我得到一个错误,因为列中的非float数据会导致问题。

我想要一个方法,我可以在df上运行,这将删除错误的行,并通知我它们存在。在我上面的例子中,结果df看起来像这样df:

mydictclean = {'colFloat': [1.5, 2.3, 3.5, 7.8], 'colBool': ['FALSE', 'TRUE', 'TRUE', 'TRUE'], 'colInt': [2, 2, 1, 4]}
dfclean = pd.DataFrame(data = mydictclean)

我尝试在read_csv调用中使用dtype参数指定dtypes,但是当函数遇到坏行时,会抛出错误。谢谢你的帮助!

您可以使用一组转换器,然后删除具有nan的行:

types = {'colFloat': 'numeric', 'colInt': 'numeric', 'colBool': 'boolean'}
converter = {'numeric': lambda s: pd.to_numeric(s, errors='coerce'),
'boolean': lambda s: s.str.upper().map({'TRUE': True, 'FALSE': False})
}
dfclean = pd.DataFrame(index=df.index)
for c, t in types.items():
dfclean[c] = converter[t](df[c])

dfclean = dfclean.dropna()
print(dfclean)

输出:

colFloat  colInt colBool
0       1.5     2.0   False
1       2.3     2.0    True
4       3.5     1.0    True
5       7.8     4.0    True

NB。对于int/float,使用pandas维护它并不总是那么容易。您可以使用convert_dtypes执行自动化(安全)浮动→

所有值都没有小数部分的Int转换。

我会尝试在所有列中同时捕获所有类型错误和CONVERT。

参见如何检查字符串是否为数字(float)?对于第一个函数:

def is_number(n):
is_number = True
try:
num = float(n)
# check for "nan" floats
is_number = num == num   # or use `math.isnan(num)`
except ValueError:
is_number = False
return is_number

然后你自己的:

def check_and_convert_int(x):
if x.is_integer():
return int(x)
else:
return np.nan
def check_and_convert_bool(x):
if x in [True, 'True', 'TRUE']:
return True
elif x in [False, 'False', 'FALSE']:
return False
else:
return np.nan
def check_and_convert_float(x):
if is_number(x):
return float(x)
else:
return np.nan

那么我会做:

df['int_col_clean'] = df['int_col'].apply(lambda x: check_and_convert_int(x))
df['bool_col_clean'] = df['bool_col'].apply(lambda x: check_and_convert_bool(x))        
df['float_col_clean'] = df['float_col'].apply(lambda x: check_and_convert_float(x))

检查可能被删除的列:

df[df.isna().any(axis=1)]

如果一切正常,把它们丢掉:

df = df.dropna(subset = ['int_col_clean', 'bool_col_clean', 'float_col_clean']) 

我必须改变布尔值,因为它们现在的方式是字符串:

mydict = {'colFloat': [1.5, 2.3,'TRUE', 'FALSE', 3.5, 7.8], 'colBool': [False, True, 3.2, 1.1, True, True], 'colInt': [2, 2, 3.7, 9.9, 1, 4]}
df = pd.DataFrame(data = mydict)

然后你可以根据实例类型进行过滤:

df = df[df['colFloat'].apply(isinstance, args=[float])]
df = df[df['colBool'].apply(isinstance, args=[bool])]
df['colInt'] = df['colInt'].astype(int)
df = df[df['colInt'].apply(isinstance, args=[int])]
df

输出:

colFloat    colBool colInt
0   1.5         False   2
1   2.3         True    2
4   3.5         True    1
5   7.8         True    4

try this:

df.loc[(df.colFloat.apply(lambda x: type(x) == float)) ]

但是你的boolcol不是bool。

相关内容

  • 没有找到相关文章