如果行(不是单独的列)包含字符串,则删除行
Delete rows if rows (not columns separately) contain a string
我从 CSV 导入数据,我用 'EMPTYFIELD' 值替换空字段。
pd.read_csv('myFile.csv', usecols=['AAA', 'BBB', 'CCC'])
df = df.fillna('EMPTYFIELD')
我正在尝试创建一个数据框,其中的所有行都包含 'EMPTYFIELD' 值。这意味着至少一列包含此值。我使用了以下内容并且它正常工作:
error = df[df.AAA.str.contains('EMPTYFIELD')]
error = error[error.BBB.str.contains('EMPTYFIELD')]
error = error[error.CCC.str.contains('EMPTYFIELD')]
现在,我正在尝试减少代码中的行数。所以,我正在考虑使用 lambda 而不是引用列(理想):
error2 = df.apply(lambda x: 'EMPTYFIELD' if 'EMPTYFIELD' in x else x)
#error2 = df.apply(lambda x : any([ isinstance(e, 'EMPTYFIELD') for e in x ]), axis=1)
然后我也尝试引用这些列:
error2 = df[usecols].apply(lambda x: 'EMPTYFIELD' if 'EMPTYFIELD' in x else x)
和
error2 = df[df[usecols].isin(['EMPTYFIELD'])]
None 以上作品。我将结果打印在一个新的 CSV 文件中。我可以看到所有行,即使它们包含 'EMPTYFIELD' 值。
UPD:这是我的扩展代码。一些答案 return 由于以下几行可能会出错:
varA = 'AAA';
dfGrouped = df.groupby(varA, as_index=False).agg({'Start Date': 'min', 'End Date': 'max'}).copy()
varsToKeep = ['AAA', 'BBB', 'CCC', 'Start Date_grp', 'End Date_grp' ]
dfTemp = pd.merge(df, dfGrouped, how='inner', on='AAA', suffixes=(' ', '_grp'), copy=True)[varsToKeep]
errors = dfTemp[~np.logical_or.reduce([dfTemp[varsToKeep].str.contains('EMPTYFIELD') for varsToKeep in dfTemp])]
一种方法是使用 np.logical_or.reduce
。这是一个例子:
import pandas as pd, numpy as np
df = pd.DataFrame([['A', 'B', 'C', 'D'],
['E', 'F', 'G', 'H'],
['G', 'A', 'D', 'I'],
['L', 'K', 'A', 'J'],
['S', 'T', 'U', 'V']],
columns=['COL1', 'COL2', 'COL3' ,'COL4'])
df[~np.logical_or.reduce([df[col].astype(str).str.contains('A') for col in df])]
# COL1 COL2 COL3 COL4
# 1 E F G H
# 4 S T U V
正如我提到的使用 apply
,来自 jp
的数据
df[~df.apply(lambda x : x.str.contains('A')).any(1)]
Out[491]:
COL1 COL2 COL3 COL4
1 E F G H
4 S T U V
下面是如何使用 dropna()
的说明,因为我 :
df = pd.DataFrame(
{'A': [5,3,5,6],
'B': [None, "foo", "bar", "foobar"],
'C': ["foo","bar",None, "bat"]
}
)
no_errors = df.dropna()
errors = df[~(df.index.isin(no_errors.index))]
这会产生以下 2 个数据帧:
print(no_errors)
# A B C
#1 3 foo bar
#3 6 foobar bat
print(errors)
# A B C
#0 5 None foo
#2 5 bar None
现在,如果需要,您可以在错误 DataFrame 上调用 fillna()
。
我从 CSV 导入数据,我用 'EMPTYFIELD' 值替换空字段。
pd.read_csv('myFile.csv', usecols=['AAA', 'BBB', 'CCC'])
df = df.fillna('EMPTYFIELD')
我正在尝试创建一个数据框,其中的所有行都包含 'EMPTYFIELD' 值。这意味着至少一列包含此值。我使用了以下内容并且它正常工作:
error = df[df.AAA.str.contains('EMPTYFIELD')]
error = error[error.BBB.str.contains('EMPTYFIELD')]
error = error[error.CCC.str.contains('EMPTYFIELD')]
现在,我正在尝试减少代码中的行数。所以,我正在考虑使用 lambda 而不是引用列(理想):
error2 = df.apply(lambda x: 'EMPTYFIELD' if 'EMPTYFIELD' in x else x)
#error2 = df.apply(lambda x : any([ isinstance(e, 'EMPTYFIELD') for e in x ]), axis=1)
然后我也尝试引用这些列:
error2 = df[usecols].apply(lambda x: 'EMPTYFIELD' if 'EMPTYFIELD' in x else x)
和
error2 = df[df[usecols].isin(['EMPTYFIELD'])]
None 以上作品。我将结果打印在一个新的 CSV 文件中。我可以看到所有行,即使它们包含 'EMPTYFIELD' 值。
UPD:这是我的扩展代码。一些答案 return 由于以下几行可能会出错:
varA = 'AAA';
dfGrouped = df.groupby(varA, as_index=False).agg({'Start Date': 'min', 'End Date': 'max'}).copy()
varsToKeep = ['AAA', 'BBB', 'CCC', 'Start Date_grp', 'End Date_grp' ]
dfTemp = pd.merge(df, dfGrouped, how='inner', on='AAA', suffixes=(' ', '_grp'), copy=True)[varsToKeep]
errors = dfTemp[~np.logical_or.reduce([dfTemp[varsToKeep].str.contains('EMPTYFIELD') for varsToKeep in dfTemp])]
一种方法是使用 np.logical_or.reduce
。这是一个例子:
import pandas as pd, numpy as np
df = pd.DataFrame([['A', 'B', 'C', 'D'],
['E', 'F', 'G', 'H'],
['G', 'A', 'D', 'I'],
['L', 'K', 'A', 'J'],
['S', 'T', 'U', 'V']],
columns=['COL1', 'COL2', 'COL3' ,'COL4'])
df[~np.logical_or.reduce([df[col].astype(str).str.contains('A') for col in df])]
# COL1 COL2 COL3 COL4
# 1 E F G H
# 4 S T U V
正如我提到的使用 apply
,来自 jp
df[~df.apply(lambda x : x.str.contains('A')).any(1)]
Out[491]:
COL1 COL2 COL3 COL4
1 E F G H
4 S T U V
下面是如何使用 dropna()
的说明,因为我
df = pd.DataFrame(
{'A': [5,3,5,6],
'B': [None, "foo", "bar", "foobar"],
'C': ["foo","bar",None, "bat"]
}
)
no_errors = df.dropna()
errors = df[~(df.index.isin(no_errors.index))]
这会产生以下 2 个数据帧:
print(no_errors)
# A B C
#1 3 foo bar
#3 6 foobar bat
print(errors)
# A B C
#0 5 None foo
#2 5 bar None
现在,如果需要,您可以在错误 DataFrame 上调用 fillna()
。