【问题标题】:Delete rows if rows (not columns separately) contain a string如果行(不是单独的列)包含字符串,则删除行
【发布时间】:2018-07-26 12:24:17
【问题描述】:

我从 CSV 导入数据,在该 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'])]

以上都不起作用。我将结果打印在一个新的 CSV 文件中。即使它们包含“EMPTYFIELD”值,我也可以看到所有行。

UPD:这是我的扩展代码。由于以下几行,一些答案可能返回错误:

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])]

【问题讨论】:

  • “现在,我正在尝试减少行”这是什么意思?
  • 如果你想删除包含错误字段的行,为什么不直接使用df[~df.AAA.str.contains('EMPTYFIELD')]
  • @pault 我不想引用列名。 AAA 是其中一列。
  • 您可以使用dropna() 创建第二个DataFrame。然后使用第二个的索引过滤第一个。

标签: python pandas csv lambda contains


【解决方案1】:

一种方法是使用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

【讨论】:

  • @试过了。我收到错误可能是因为这(我的问题中的更新)会影响代码。
  • Can only use .str accessor with string values, which use np.object_ dtype in pandas
  • @ApoloRadomer。好的,它解释了自己。我现在更新了代码供你试用。
  • 干净整洁。我将搜索这背后的确切逻辑。我的意思是每个“命令”都可以。
【解决方案2】:

这里是如何使用dropna()作为我mentioned in the comments的说明:

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()

【讨论】:

  • 如果我在打印前先使用dropna(),然后使用group by,那就可以了。基于一列 (A),假设我们有一个 ID 11111。这个 ID 有 5 行,没有空字段。然后我们有 1 行,其中一列 (B) 有一个空值。我希望此 ID 的所有 6 行都算作错误。
【解决方案3】:

正如我提到的使用 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

【讨论】:

  • 返回错误:('Can only use .str accessor with string values, which use np.object_ dtype in pandas', 'occurred at index AAA')。在使用您的线路之前,我先分组,然后使用以下内容:pd.merge(df, dfGrouped, how='inner', on='AAA', suffixes=(' ', '_grp'), copy=True)[varsToKeep]
猜你喜欢
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 1970-01-01
  • 2019-06-17
相关资源
最近更新 更多