根据列值删除Pandas中的DataFrame行

我有以下DataFrame:

             daysago  line_race rating        rw    wratingline_date2007-03-31       62         11     56  1.000000  56.0000002007-03-10       83         11     67  1.000000  67.0000002007-02-10      111          9     66  1.000000  66.0000002007-01-13      139         10     83  0.880678  73.0962782006-12-23      160         10     88  0.793033  69.7869422006-11-09      204          9     52  0.636655  33.1060772006-10-22      222          8     66  0.581946  38.4084082006-09-29      245          9     70  0.518825  36.3177522006-09-16      258         11     68  0.486226  33.0633812006-08-30      275          8     72  0.446667  32.1600512006-02-11      475          5     65  0.164591  10.6984232006-01-13      504          0     70  0.142409   9.9686342006-01-02      515          0     64  0.134800   8.6272192005-12-06      542          0     70  0.117803   8.2462382005-11-29      549          0     70  0.113758   7.9630722005-11-22      556          0     -1  0.109852  -0.1098522005-11-01      577          0     -1  0.098919  -0.0989192005-10-20      589          0     -1  0.093168  -0.0931682005-09-27      612          0     -1  0.083063  -0.0830632005-09-07      632          0     -1  0.075171  -0.0751712005-06-12      719          0     69  0.048690   3.3596232005-05-29      733          0     -1  0.045404  -0.0454042005-05-02      760          0     -1  0.039679  -0.0396792005-04-02      790          0     -1  0.034160  -0.0341602005-03-13      810          0     -1  0.030915  -0.0309152004-11-09      934          0     -1  0.016647  -0.016647

我需要删除line_race等于0的行。什么是最有效的方法?

1658150 次浏览

如果我理解正确,它应该像这样简单:

df = df[df.line_race != 0]

最好的方法是使用布尔掩码:

In [56]: dfOut[56]:line_date  daysago  line_race  rating    raw  wrating0   2007-03-31       62         11      56  1.000   56.0001   2007-03-10       83         11      67  1.000   67.0002   2007-02-10      111          9      66  1.000   66.0003   2007-01-13      139         10      83  0.881   73.0964   2006-12-23      160         10      88  0.793   69.7875   2006-11-09      204          9      52  0.637   33.1066   2006-10-22      222          8      66  0.582   38.4087   2006-09-29      245          9      70  0.519   36.3188   2006-09-16      258         11      68  0.486   33.0639   2006-08-30      275          8      72  0.447   32.16010  2006-02-11      475          5      65  0.165   10.69811  2006-01-13      504          0      70  0.142    9.96912  2006-01-02      515          0      64  0.135    8.62713  2005-12-06      542          0      70  0.118    8.24614  2005-11-29      549          0      70  0.114    7.96315  2005-11-22      556          0      -1  0.110   -0.11016  2005-11-01      577          0      -1  0.099   -0.09917  2005-10-20      589          0      -1  0.093   -0.09318  2005-09-27      612          0      -1  0.083   -0.08319  2005-09-07      632          0      -1  0.075   -0.07520  2005-06-12      719          0      69  0.049    3.36021  2005-05-29      733          0      -1  0.045   -0.04522  2005-05-02      760          0      -1  0.040   -0.04023  2005-04-02      790          0      -1  0.034   -0.03424  2005-03-13      810          0      -1  0.031   -0.03125  2004-11-09      934          0      -1  0.017   -0.017
In [57]: df[df.line_race != 0]Out[57]:line_date  daysago  line_race  rating    raw  wrating0   2007-03-31       62         11      56  1.000   56.0001   2007-03-10       83         11      67  1.000   67.0002   2007-02-10      111          9      66  1.000   66.0003   2007-01-13      139         10      83  0.881   73.0964   2006-12-23      160         10      88  0.793   69.7875   2006-11-09      204          9      52  0.637   33.1066   2006-10-22      222          8      66  0.582   38.4087   2006-09-29      245          9      70  0.519   36.3188   2006-09-16      258         11      68  0.486   33.0639   2006-08-30      275          8      72  0.447   32.16010  2006-02-11      475          5      65  0.165   10.698

更新:现在熊猫0.13已经出来了,另一种方法是df.query('line_race != 0')

但是对于任何未来的旁观者,你可以提到df = df[df.line_race != 0]在尝试过滤None/缺失值时没有做任何事情。

工作:

df = df[df.line_race != 0]

不做任何事情:

df = df[df.line_race != None]

工作:

df = df[df.line_race.notnull()]

给出的答案是正确的,但上面有人说你可以使用df.query('line_race != 0'),这取决于你的问题,速度要快得多。强烈推荐。

只是为了添加另一个解决方案,特别有用,如果你正在使用新的熊猫评估器,其他解决方案将取代原来的熊猫并失去评估器

df.drop(df.loc[df['line_race']==0].index, inplace=True)

另一种方法。可能不是最有效的方法,因为代码看起来比其他答案中提到的代码更复杂,但仍然可以替代做同样的事情。

  df = df.drop(df[df['line_race']==0].index)

虽然前面的答案与我要做的几乎相似,但使用index方法并不需要使用另一种索引方法. loc()。它可以以类似但精确的方式完成

df.drop(df.index[df['line_race'] == 0], inplace = True)

如果要根据列的多个值删除行,可以使用:

df[(df.line_race != 0) & (df.line_race != 10)]

删除line_race的值为0和10的所有行。

只是为DataFrame在所有列上扩展添加另一种方式:

for column in df.columns:df = df[df[column]!=0]

示例:

def z_score(data,count):threshold=3for column in data.columns:mean = np.mean(data[column])std = np.std(data[column])for i in data[column]:zscore = (i-mean)/stdif(np.abs(zscore)>threshold):count=count+1data = data[data[column]!=i]return data,count

我编译并运行了我的代码。这是准确的代码。您可以自己尝试。

data = pd.read_excel('file.xlsx')

如果您在列名中有任何特殊字符或空格,您可以像在给定代码中一样将其写入''

data = data[data['expire/t'].notnull()]print (date)

如果只有一个字符串列名,没有任何空格或特殊您可以直接访问它的字符。

data = data[data.expire ! = 0]print (date)

在多个值和str dtype的情况下

我使用以下方法来过滤掉Coll中的给定值:

def filter_rows_by_values(df, col, values):return df[~df[col].isin(values)]

示例:

在DataFrame中,我想删除在“str”列中具有值“b”和“c”的行

df = pd.DataFrame({"str": ["a","a","a","a","b","b","c"], "other": [1,2,3,4,5,6,7]})dfstr  other0   a   11   a   22   a   33   a   44   b   55   b   66   c   7
filter_rows_by_values(df, "str", ["b","c"])
str  other0   a   11   a   22   a   33   a   4

添加另一种方法来做到这一点。

 df = df.query("line_race!=0")

其中一个有效且混乱的方法是使用eq()方法:

df[~df.line_race.eq(0)]

以防您需要删除行,但值可以在不同的列中。在我的情况下,我使用百分比,所以我想删除任何列中值为1的行,因为这意味着它是100%

for x in df:df.drop(df.loc[df[x]==1].index, inplace=True)

如果您的df有太多列,则不是最佳的。

对于像这样的简单示例,它没有太大的区别,但对于复杂的逻辑,我更喜欢在删除行时使用drop(),因为它比使用逆逻辑更直接。例如,删除A=1 AND (B=2 OR C=3)的行。

这是一个易于理解并且可以处理复杂逻辑的可扩展语法:

df.drop( df.query(" `line_race` == 0 ").index)

你可以尝试使用这个:

df.drop(df[df.line_race != 0].index, inplace = True)

.

有多种方法可以实现这一点。将在下面留下各种选项,可以使用,具体取决于用例的特殊性。

人们会认为OP的数据帧存储在变量df中。


备选案文1

对于OP的情况,考虑到值为0的唯一列是line_race,下面将完成工作

 df_new = df[df != 0].dropna() 
[Out]:line_date  daysago  line_race  rating        rw    wrating0   2007-03-31       62       11.0      56  1.000000  56.0000001   2007-03-10       83       11.0      67  1.000000  67.0000002   2007-02-10      111        9.0      66  1.000000  66.0000003   2007-01-13      139       10.0      83  0.880678  73.0962784   2006-12-23      160       10.0      88  0.793033  69.7869425   2006-11-09      204        9.0      52  0.636655  33.1060776   2006-10-22      222        8.0      66  0.581946  38.4084087   2006-09-29      245        9.0      70  0.518825  36.3177528   2006-09-16      258       11.0      68  0.486226  33.0633819   2006-08-30      275        8.0      72  0.446667  32.16005110  2006-02-11      475        5.0      65  0.164591  10.698423

但是,由于情况并非总是如此,建议检查以下选项,其中一个将指定列名。


备选案文2

tshauck的方法最终比选项1更好,因为可以指定列。但是,根据想要引用列的方式,还有其他变化:

例如,使用数据框中的位置

df_new = df[df[df.columns[2]] != 0]

或通过如下方式明确指出列

df_new = df[df['line_race'] != 0]

也可以遵循相同的登录,但使用自定义lambda函数,例如

df_new = df[df.apply(lambda x: x['line_race'] != 0, axis=1)]
[Out]:line_date  daysago  line_race  rating        rw    wrating0   2007-03-31       62       11.0      56  1.000000  56.0000001   2007-03-10       83       11.0      67  1.000000  67.0000002   2007-02-10      111        9.0      66  1.000000  66.0000003   2007-01-13      139       10.0      83  0.880678  73.0962784   2006-12-23      160       10.0      88  0.793033  69.7869425   2006-11-09      204        9.0      52  0.636655  33.1060776   2006-10-22      222        8.0      66  0.581946  38.4084087   2006-09-29      245        9.0      70  0.518825  36.3177528   2006-09-16      258       11.0      68  0.486226  33.0633819   2006-08-30      275        8.0      72  0.446667  32.16005110  2006-02-11      475        5.0      65  0.164591  10.698423

备选案文3

使用pandas.Series.map和自定义lambda函数

df_new = df['line_race'].map(lambda x: x != 0)
[Out]:line_date  daysago  line_race  rating        rw    wrating0   2007-03-31       62       11.0      56  1.000000  56.0000001   2007-03-10       83       11.0      67  1.000000  67.0000002   2007-02-10      111        9.0      66  1.000000  66.0000003   2007-01-13      139       10.0      83  0.880678  73.0962784   2006-12-23      160       10.0      88  0.793033  69.7869425   2006-11-09      204        9.0      52  0.636655  33.1060776   2006-10-22      222        8.0      66  0.581946  38.4084087   2006-09-29      245        9.0      70  0.518825  36.3177528   2006-09-16      258       11.0      68  0.486226  33.0633819   2006-08-30      275        8.0      72  0.446667  32.16005110  2006-02-11      475        5.0      65  0.164591  10.698423

备选办法4

使用pandas.DataFrame.drop如下

df_new = df.drop(df[df['line_race'] == 0].index)
[Out]:line_date  daysago  line_race  rating        rw    wrating0   2007-03-31       62       11.0      56  1.000000  56.0000001   2007-03-10       83       11.0      67  1.000000  67.0000002   2007-02-10      111        9.0      66  1.000000  66.0000003   2007-01-13      139       10.0      83  0.880678  73.0962784   2006-12-23      160       10.0      88  0.793033  69.7869425   2006-11-09      204        9.0      52  0.636655  33.1060776   2006-10-22      222        8.0      66  0.581946  38.4084087   2006-09-29      245        9.0      70  0.518825  36.3177528   2006-09-16      258       11.0      68  0.486226  33.0633819   2006-08-30      275        8.0      72  0.446667  32.16005110  2006-02-11      475        5.0      65  0.164591  10.698423

备选办法5

使用pandas.DataFrame.query如下

df_new = df.query('line_race != 0')
[Out]:line_date  daysago  line_race  rating        rw    wrating0   2007-03-31       62       11.0      56  1.000000  56.0000001   2007-03-10       83       11.0      67  1.000000  67.0000002   2007-02-10      111        9.0      66  1.000000  66.0000003   2007-01-13      139       10.0      83  0.880678  73.0962784   2006-12-23      160       10.0      88  0.793033  69.7869425   2006-11-09      204        9.0      52  0.636655  33.1060776   2006-10-22      222        8.0      66  0.581946  38.4084087   2006-09-29      245        9.0      70  0.518825  36.3177528   2006-09-16      258       11.0      68  0.486226  33.0633819   2006-08-30      275        8.0      72  0.446667  32.16005110  2006-02-11      475        5.0      65  0.164591  10.698423

备选办法6

使用pandas.DataFrame.droppandas.DataFrame.query如下

df_new = df.drop(df.query('line_race == 0').index)
[Out]:line_date  daysago  line_race  rating        rw    wrating0   2007-03-31       62       11.0      56  1.000000  56.0000001   2007-03-10       83       11.0      67  1.000000  67.0000002   2007-02-10      111        9.0      66  1.000000  66.0000003   2007-01-13      139       10.0      83  0.880678  73.0962784   2006-12-23      160       10.0      88  0.793033  69.7869425   2006-11-09      204        9.0      52  0.636655  33.1060776   2006-10-22      222        8.0      66  0.581946  38.4084087   2006-09-29      245        9.0      70  0.518825  36.3177528   2006-09-16      258       11.0      68  0.486226  33.0633819   2006-08-30      275        8.0      72  0.446667  32.16005110  2006-02-11      475        5.0      65  0.164591  10.698423

备选办法7

如果对输出没有强烈的意见,可以使用numpy.select的矢量化方法

df_new = np.select([df != 0], [df], default=np.nan)
[Out]:[['2007-03-31' 62 11.0 56 1.0 56.0]['2007-03-10' 83 11.0 67 1.0 67.0]['2007-02-10' 111 9.0 66 1.0 66.0]['2007-01-13' 139 10.0 83 0.880678 73.096278]['2006-12-23' 160 10.0 88 0.793033 69.786942]['2006-11-09' 204 9.0 52 0.636655 33.106077]['2006-10-22' 222 8.0 66 0.581946 38.408408]['2006-09-29' 245 9.0 70 0.518825 36.317752]['2006-09-16' 258 11.0 68 0.486226 33.063381]['2006-08-30' 275 8.0 72 0.446667 32.160051]['2006-02-11' 475 5.0 65 0.164591 10.698423]]

这也可以转换为数据框

df_new = pd.DataFrame(df_new, columns=df.columns)
[Out]:line_date daysago line_race rating        rw    wrating0   2007-03-31      62      11.0     56       1.0       56.01   2007-03-10      83      11.0     67       1.0       67.02   2007-02-10     111       9.0     66       1.0       66.03   2007-01-13     139      10.0     83  0.880678  73.0962784   2006-12-23     160      10.0     88  0.793033  69.7869425   2006-11-09     204       9.0     52  0.636655  33.1060776   2006-10-22     222       8.0     66  0.581946  38.4084087   2006-09-29     245       9.0     70  0.518825  36.3177528   2006-09-16     258      11.0     68  0.486226  33.0633819   2006-08-30     275       8.0     72  0.446667  32.16005110  2006-02-11     475       5.0     65  0.164591  10.698423

关于最有效的解决方案,这将取决于人们想要如何衡量效率。假设一个人想要衡量执行时间,一个可以去做的方法是使用time.perf_counter()

如果测量上面所有选项的执行时间,则会得到以下结果

       method                   time0    Option 1 0.000001100008375942711  Option 2.1 0.000001399952452629802  Option 2.2 0.000003699969965964563  Option 2.3 0.000001600012183189394    Option 3 0.000001100008375942715    Option 4 0.000001200009137392046    Option 5 0.000001400010660290727    Option 6 0.000001599953975528488    Option 7 0.00000150001142174006

输入图片描述

但是,这可能会根据使用的数据帧、需求(例如硬件)等而改变。


备注:

提供了这么多选项(也许我没有太注意,如果是这样的话,对不起),但没有人提到这一点:我们可以在熊猫中使用这个符号:~(这给了我们条件的倒数)

df = df[~df["line_race"] == 0]