【问题标题】:Filter pandas dataframe based on values in multiple columns根据多列中的值过滤熊猫数据框
【发布时间】:2016-08-31 14:04:37
【问题描述】:

我有一个包含 472 列的数据框。这 99 列中有 dxpoa1、dxpoa2、...、dxpoa99。我想过滤掉 dxpoa 列的值为 7 或 N 或 BLANK 的数据帧行。 dxpoa 可以有许多值,例如 Y、W、E、1、7、N 等。或者它们保持空白。只有那些 dxpoa 只有 7 或 N 的行才应该从数据框中过滤掉。 数据集很大,有数十万行。因此,一种有效的方法将受到赞赏。

    a  b  c dxpoa1 dxpoa2 dxpoa3 dxpoa4
0   0  A  X      W      N      X       
1   Z  W  2      7      7             
2   7  W  N      W      W      1      Z
3   1  7  E      N      N      N      N
4   Y     0      W      N      X      1
5   N  X  1      E      1      Z      7
6   1  X  7      0      A      W      A
7   X  X  Z      X      N      A      1
8   7  1  A      N      X      Z      N
9   N  A  Z      N      N      N
10  A  N  Z      7      0      A      E
11  E  N  A      Z      N      N      1
12  E  A  1      Z      E      E      W
13  N  W  Z      E      X      A      0
14  Y  1  A      W      A      E      X

我想从数据框中删除第 1、3、9 行。

我尝试了很多方法,例如:

df_col = [list of dxpoa column names]
df1 = df[df_col].isin(["Y", "W", "1", "E"]).values

它不会过滤掉。

【问题讨论】:

  • 您想删除 any 的 dxpoa 列中包含 '7''N' 的行还是只删除 所有这些列都包含'7''N'
  • 我只想删除部分或全部列可能包含“7”或“N”的行。如果行有 7、N、E、W 等或 7、N 以外的混合,那么我想保留这些行。在第一行中,我写了“一些”,因为没有必要让所有 dxpoa 列都有值。许多列也是空白。这些列是值的占位符。在某些行中,只有 1 或 2 会有值,而在某些行中,所有 dxpoa 都会有值。
  • 最好将空白视为空字符串,''——类似于'7''N' 的值。然后,您可以将问题表达为删除 all 值(在 dxpoa 列中)在 ['7', 'N', ''] 中的行之一。
  • 我用确切的场景更新了你提供的数据框。我想从数据框中删除第 1、3、9 行。

标签: python-3.x numpy pandas


【解决方案1】:

更新:

您可以将空字符串替换为NaN7N,然后使用isin

In [196]: df[~df[cols].replace('',np.nan).isin(['7','N', np.nan]).all(axis=1)]
Out[196]:
    a  b  c dxpoa1 dxpoa2 dxpoa3 dxpoa4
0   0  A  X      W      N      X
2   7  W  N      W      W      1      Z
4   Y  0  W      N      X      1
5   N  X  1      E      1      Z      7
6   1  X  7      0      A      W      A
7   X  X  Z      X      N      A      1
8   7  1  A      N      X      Z      N
10  A  N  Z      7      0      A      E
11  E  N  A      Z      N      N      1
12  E  A  1      Z      E      E      W
13  N  W  Z      E      X      A      0
14  Y  1  A      W      A      E      X

旧答案:

显示包含7N 的那些

In [197]: df.loc[df[cols].isin(['7','N']).any(axis=1)]
Out[197]:
    a  b  c dxpoa1 dxpoa2 dxpoa3 dxpoa4
0   0  A  X      W      N      X
1   Z  W  2      7      7
3   1  7  E      N      N      N      N
4   Y  0  W      N      X      1
5   N  X  1      E      1      Z      7
7   X  X  Z      X      N      A      1
8   7  1  A      N      X      Z      N
9   N  A  Z      N      N      N
10  A  N  Z      7      0      A      E
11  E  N  A      Z      N      N      1

删除那些包含7N的人

In [198]: df.loc[~df[cols].isin(['7','N']).any(axis=1)]
Out[198]:
    a  b  c dxpoa1 dxpoa2 dxpoa3 dxpoa4
2   7  W  N      W      W      1      Z
6   1  X  7      0      A      W      A
12  E  A  1      Z      E      E      W
13  N  W  Z      E      X      A      0
14  Y  1  A      W      A      E      X

如果你想拥有/排除那些所有列应该包含7N

的列,请将any替换为all

设置:

rows = 15

s = [''] + list('YWE17N0AZX')
df = pd.DataFrame(np.random.choice(s, size=(rows, 7)), columns=list('abc') + ['dxpoa1', 'dxpoa2', 'dxpoa3', 'dxpoa4'])

cols = df.filter(like='dxpoa').columns

【讨论】:

  • 它删除所有出现 7 或 N 的行以及其他值。我只想删除那些只有 7 或 N 的行
  • @Sanoj,总是乐于提供帮助
【解决方案2】:
  • 您可以使用df.filter(regex=r'^dxpoa') 选择名称以'dxpoa' 开头的列,并且
  • 使用.isin(['7','N','']).all(axis=1) 创建一个布尔掩码(对于行),当所有行中的值为'7''N' 或空字符串@ 时,该掩码为真987654326@:

例如,

import pandas as pd

df = pd.DataFrame(
    {'a': ['0','Z','7','1','Y','N','1','X','7','N','A','E','E','N','Y'],
     'b': ['A','W','W','7','','X','X','X','1','A','N','N','A','W','1'],
     'c': ['X','2','N','E','0','1','7','Z','A','Z','Z','A','1','Z','A'],
     'dxpoa1': ['W','7','W','N','W','E','0','X','N','N','7','Z','Z','E','W'],
     'dxpoa2': ['N','7','W','N','N','1','A','N','X','N','0','N','E','X','A'],
     'dxpoa3': ['X','','1','N','X','Z','W','A','Z','N','A','N','E','A','E'],
     'dxpoa4': ['','','Z','N','1','7','A','1','N','','E','1','W','0','X']})
mask = df.filter(regex=r'^dxpoa').isin(['7','N','']).all(axis=1)
print(df.loc[~mask])

产量

    a  b  c dxpoa1 dxpoa2 dxpoa3 dxpoa4
0   0  A  X      W      N      X       
2   7  W  N      W      W      1      Z
4   Y     0      W      N      X      1
5   N  X  1      E      1      Z      7
6   1  X  7      0      A      W      A
7   X  X  Z      X      N      A      1
8   7  1  A      N      X      Z      N
10  A  N  Z      7      0      A      E
11  E  N  A      Z      N      N      1
12  E  A  1      Z      E      E      W
13  N  W  Z      E      X      A      0
14  Y  1  A      W      A      E      X

【讨论】:

  • 如果您有未定义数量的具有通用名称的列(即 Area_1、Area_2、Area_3 等),这是一个更灵活的解决方案。干杯!
【解决方案3】:

使用应用。如果应用函数返回布尔值,它可用于过滤行 如下例所示。请注意,我没有尝试重现您的过滤逻辑。

def analyze_row(r):
   # do whatever you want with column values here
   # return boolean: True - row stays, False - row gone
   ret = False
   if r['dpxoa1'] == 'W':
      ret = True
   return ret

filtered_df = df.ix[df.apply(analyze_row, axis = 1), :]

【讨论】:

    猜你喜欢
    • 2020-08-08
    • 2020-08-16
    • 1970-01-01
    • 2021-12-01
    • 2013-06-09
    • 2020-05-05
    • 2014-12-27
    • 1970-01-01
    • 2019-12-09
    相关资源
    最近更新 更多