根据列值删除Pandas中的DataFrame行

Tra*_*VOX 441 python pandas

我有以下DataFrame:

             daysago  line_race rating        rw    wrating
 line_date                                                 
 2007-03-31       62         11     56  1.000000  56.000000
 2007-03-10       83         11     67  1.000000  67.000000
 2007-02-10      111          9     66  1.000000  66.000000
 2007-01-13      139         10     83  0.880678  73.096278
 2006-12-23      160         10     88  0.793033  69.786942
 2006-11-09      204          9     52  0.636655  33.106077
 2006-10-22      222          8     66  0.581946  38.408408
 2006-09-29      245          9     70  0.518825  36.317752
 2006-09-16      258         11     68  0.486226  33.063381
 2006-08-30      275          8     72  0.446667  32.160051
 2006-02-11      475          5     65  0.164591  10.698423
 2006-01-13      504          0     70  0.142409   9.968634
 2006-01-02      515          0     64  0.134800   8.627219
 2005-12-06      542          0     70  0.117803   8.246238
 2005-11-29      549          0     70  0.113758   7.963072
 2005-11-22      556          0     -1  0.109852  -0.109852
 2005-11-01      577          0     -1  0.098919  -0.098919
 2005-10-20      589          0     -1  0.093168  -0.093168
 2005-09-27      612          0     -1  0.083063  -0.083063
 2005-09-07      632          0     -1  0.075171  -0.075171
 2005-06-12      719          0     69  0.048690   3.359623
 2005-05-29      733          0     -1  0.045404  -0.045404
 2005-05-02      760          0     -1  0.039679  -0.039679
 2005-04-02      790          0     -1  0.034160  -0.034160
 2005-03-13      810          0     -1  0.030915  -0.030915
 2004-11-09      934          0     -1  0.016647  -0.016647
Run Code Online (Sandbox Code Playgroud)

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

tsh*_*uck 761

如果我理解正确,它应该如下:

df = df[df.line_race != 0]
Run Code Online (Sandbox Code Playgroud)

  • @vfxGer如果列中有空格,比如'line race',那么你可以做`df = df [df ['line race']!= 0] (38认同)
  • 如果`df`很大,这会花费更多内存吗?或者,我可以在原地进行吗? (15认同)
  • 只需在带有2M行的`df`上运行它就会非常快. (7认同)
  • 如果我们想要删除整行,如果在该行的任何列中找到有问题的值,我们将如何修改此命令? (2认同)
  • 谢谢!首先,对我来说,这必须是df = df [〜df ['DATE']。isin(['2015-10-30.1','2015-11-30.1','2015-12-31.1'])] ` (2认同)
  • 如果你有多个条件,你可以这样做: `df = df[df['line race'] != 0| df['line race'].isin([1,2])]` 使用`|`作为`or`,使用`&`作为`and`,你可以使用`isin(Iterable)`作为python的`in` (2认同)

won*_*id2 168

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

工作:

df = df[df.line_race != 0]
Run Code Online (Sandbox Code Playgroud)

什么都不做:

df = df[df.line_race != None]
Run Code Online (Sandbox Code Playgroud)

工作:

df = df[df.line_race.notnull()]
Run Code Online (Sandbox Code Playgroud)

  • 如果我们不知道列名,该怎么做? (4认同)
  • 可以执行`df = df[df.columns[2].notnull()]`,但是无论如何您需要能够以某种方式索引该列。 (2认同)
  • `df = df[df.line_race != 0]` 会删除行,但也不重置索引。因此,当您在 df 中添加另一行时,它可能不会添加到末尾。我建议在该操作后重置索引(`df = df.reset_index(drop=True)`) (2认同)
  • 您永远不应该使用 == 运算符来开始与 None 进行比较。/sf/ask/228054361/ Between-is-none-and-none (2认同)
  • 对于“None”值,您可以使用“is”代替“==”,使用“is not”代替“!=”,如本例所示,“df = df[df.line_race is not None]”将起作用 (2认同)

Phi*_*oud 39

执行此操作的最佳方法是使用布尔掩码:

In [56]: df
Out[56]:
     line_date  daysago  line_race  rating    raw  wrating
0   2007-03-31       62         11      56  1.000   56.000
1   2007-03-10       83         11      67  1.000   67.000
2   2007-02-10      111          9      66  1.000   66.000
3   2007-01-13      139         10      83  0.881   73.096
4   2006-12-23      160         10      88  0.793   69.787
5   2006-11-09      204          9      52  0.637   33.106
6   2006-10-22      222          8      66  0.582   38.408
7   2006-09-29      245          9      70  0.519   36.318
8   2006-09-16      258         11      68  0.486   33.063
9   2006-08-30      275          8      72  0.447   32.160
10  2006-02-11      475          5      65  0.165   10.698
11  2006-01-13      504          0      70  0.142    9.969
12  2006-01-02      515          0      64  0.135    8.627
13  2005-12-06      542          0      70  0.118    8.246
14  2005-11-29      549          0      70  0.114    7.963
15  2005-11-22      556          0      -1  0.110   -0.110
16  2005-11-01      577          0      -1  0.099   -0.099
17  2005-10-20      589          0      -1  0.093   -0.093
18  2005-09-27      612          0      -1  0.083   -0.083
19  2005-09-07      632          0      -1  0.075   -0.075
20  2005-06-12      719          0      69  0.049    3.360
21  2005-05-29      733          0      -1  0.045   -0.045
22  2005-05-02      760          0      -1  0.040   -0.040
23  2005-04-02      790          0      -1  0.034   -0.034
24  2005-03-13      810          0      -1  0.031   -0.031
25  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  wrating
0   2007-03-31       62         11      56  1.000   56.000
1   2007-03-10       83         11      67  1.000   67.000
2   2007-02-10      111          9      66  1.000   66.000
3   2007-01-13      139         10      83  0.881   73.096
4   2006-12-23      160         10      88  0.793   69.787
5   2006-11-09      204          9      52  0.637   33.106
6   2006-10-22      222          8      66  0.582   38.408
7   2006-09-29      245          9      70  0.519   36.318
8   2006-09-16      258         11      68  0.486   33.063
9   2006-08-30      275          8      72  0.447   32.160
10  2006-02-11      475          5      65  0.165   10.698
Run Code Online (Sandbox Code Playgroud)

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

  • `query`的好更新.它允许更丰富的选择标准(例如类似集合的操作,如`df.query('var_list'中的变量)`其中'var_list'是所需值的列表) (14认同)
  • 我会避免在标题中有空格,例如`df = df.rename(columns = lambda x:x.strip().replace('','_'))` (3认同)
  • 如果列名中有空格,`query`不是很有用. (2认同)

des*_*ond 26

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

df.drop(df.loc[df['line_race']==0].index, inplace=True)
Run Code Online (Sandbox Code Playgroud)

  • 编写索引和就地的目的是什么。谁能解释一下? (4认同)
  • [阅读文档!](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.drop.html#pandas.DataFrame.drop) (3认同)
  • 我认为如果有人最终使用索引访问器,我们也需要 `.reset_index()` (2认同)
  • 这确实是数据搜索和删除中使用的正确答案。在这里添加更多解释。df['line_race']==0].index -> 这将找到所有值为 0 的 'line_race' 列的行索引。 inplace=True -> 这将修改原始数据帧 df。如果您不想修改原始数据帧,请删除 if(默认为 False)并将返回值存储在另一个数据帧中。 (2认同)

Loo*_*hie 22

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

df.drop(df.index[df['line_race'] == 0], inplace = True)
Run Code Online (Sandbox Code Playgroud)

  • 就地解决方案更适合大型数据集或内存受限。+1 (2认同)

小智 17

如果有多个值和 str dtype

我使用以下内容过滤掉 col 中的给定值:

def filter_rows_by_values(df, col, values):
    return df[df[col].isin(values) == False]
Run Code Online (Sandbox Code Playgroud)

例子:

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

df = pd.DataFrame({"str": ["a","a","a","a","b","b","c"], "other": [1,2,3,4,5,6,7]})
df
   str  other
0   a   1
1   a   2
2   a   3
3   a   4
4   b   5
5   b   6
6   c   7

filter_rows_by_values(d,"str", ["b","c"])

   str  other
0   a   1
1   a   2
2   a   3
3   a   4
Run Code Online (Sandbox Code Playgroud)

  • 我也喜欢这个。可能完全过时了,但添加了一个小参数来帮助我决定是选择还是删除它。如果你想将 df 一分为二,这会很方便:`def filter_rows_by_values(df, col, values, true_or_false = False): return df[df[col].isin(values) == true_or_false]` (3认同)

h3h*_*325 13

给出的答案是正确的,尽管如上所述,你可以使用df.query('line_race != 0')哪个取决于你的问题要快得多.极力推荐.


Gon*_*ica 9

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

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


选项1

对于OP的情况,考虑到唯一具有值的列0line_race,以下将完成工作

 df_new = df[df != 0].dropna()
 
[Out]:
     line_date  daysago  line_race  rating        rw    wrating
0   2007-03-31       62       11.0      56  1.000000  56.000000
1   2007-03-10       83       11.0      67  1.000000  67.000000
2   2007-02-10      111        9.0      66  1.000000  66.000000
3   2007-01-13      139       10.0      83  0.880678  73.096278
4   2006-12-23      160       10.0      88  0.793033  69.786942
5   2006-11-09      204        9.0      52  0.636655  33.106077
6   2006-10-22      222        8.0      66  0.581946  38.408408
7   2006-09-29      245        9.0      70  0.518825  36.317752
8   2006-09-16      258       11.0      68  0.486226  33.063381
9   2006-08-30      275        8.0      72  0.446667  32.160051
10  2006-02-11      475        5.0      65  0.164591  10.698423
Run Code Online (Sandbox Code Playgroud)

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


选项2

tshauck 的方法最终比选项 1 更好,因为可以指定列。然而,根据人们想要如何引用该列,还有其他变化:

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

df_new = df[df[df.columns[2]] != 0]
Run Code Online (Sandbox Code Playgroud)

或者通过明确指示该列,如下所示

df_new = df[df['line_race'] != 0]
Run Code Online (Sandbox Code Playgroud)

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

df_new = df[df.apply(lambda x: x['line_race'] != 0, axis=1)]

[Out]:
     line_date  daysago  line_race  rating        rw    wrating
0   2007-03-31       62       11.0      56  1.000000  56.000000
1   2007-03-10       83       11.0      67  1.000000  67.000000
2   2007-02-10      111        9.0      66  1.000000  66.000000
3   2007-01-13      139       10.0      83  0.880678  73.096278
4   2006-12-23      160       10.0      88  0.793033  69.786942
5   2006-11-09      204        9.0      52  0.636655  33.106077
6   2006-10-22      222        8.0      66  0.581946  38.408408
7   2006-09-29      245        9.0      70  0.518825  36.317752
8   2006-09-16      258       11.0      68  0.486226  33.063381
9   2006-08-30      275        8.0      72  0.446667  32.160051
10  2006-02-11      475        5.0      65  0.164591  10.698423
Run Code Online (Sandbox Code Playgroud)

选项3

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

df_new = df['line_race'].map(lambda x: x != 0)

[Out]:
     line_date  daysago  line_race  rating        rw    wrating
0   2007-03-31       62       11.0      56  1.000000  56.000000
1   2007-03-10       83       11.0      67  1.000000  67.000000
2   2007-02-10      111        9.0      66  1.000000  66.000000
3   2007-01-13      139       10.0      83  0.880678  73.096278
4   2006-12-23      160       10.0      88  0.793033  69.786942
5   2006-11-09      204        9.0      52  0.636655  33.106077
6   2006-10-22      222        8.0      66  0.581946  38.408408
7   2006-09-29      245        9.0      70  0.518825  36.317752
8   2006-09-16      258       11.0      68  0.486226  33.063381
9   2006-08-30      275        8.0      72  0.446667  32.160051
10  2006-02-11      475        5.0      65  0.164591  10.698423
Run Code Online (Sandbox Code Playgroud)

选项4

使用pandas.DataFrame.drop如下

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

[Out]:
     line_date  daysago  line_race  rating        rw    wrating
0   2007-03-31       62       11.0      56  1.000000  56.000000
1   2007-03-10       83       11.0      67  1.000000  67.000000
2   2007-02-10      111        9.0      66  1.000000  66.000000
3   2007-01-13      139       10.0      83  0.880678  73.096278
4   2006-12-23      160       10.0      88  0.793033  69.786942
5   2006-11-09      204        9.0      52  0.636655  33.106077
6   2006-10-22      222        8.0      66  0.581946  38.408408
7   2006-09-29      245        9.0      70  0.518825  36.317752
8   2006-09-16      258       11.0      68  0.486226  33.063381
9   2006-08-30      275        8.0      72  0.446667  32.160051
10  2006-02-11      475        5.0      65  0.164591  10.698423
Run Code Online (Sandbox Code Playgroud)

选项5

使用pandas.DataFrame.query如下

df_new = df.query('line_race != 0')

[Out]:
     line_date  daysago  line_race  rating        rw    wrating
0   2007-03-31       62       11.0      56  1.000000  56.000000
1   2007-03-10       83       11.0      67  1.000000  67.000000
2   2007-02-10      111        9.0      66  1.000000  66.000000
3   2007-01-13      139       10.0      83  0.880678  73.096278
4   2006-12-23      160       10.0      88  0.793033  69.786942
5   2006-11-09      204        9.0      52  0.636655  33.106077
6   2006-10-22      222        8.0      66  0.581946  38.408408
7   2006-09-29      245        9.0      70  0.518825  36.317752
8   2006-09-16      258       11.0      68  0.486226  33.063381
9   2006-08-30      275        8.0      72  0.446667  32.160051
10  2006-02-11      475        5.0      65  0.164591  10.698423
Run Code Online (Sandbox Code Playgroud)

选项6

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

df_new = df.drop(df.query('line_race == 0').index)

[Out]:
     line_date  daysago  line_race  rating        rw    wrating
0   2007-03-31       62       11.0      56  1.000000  56.000000
1   2007-03-10       83       11.0      67  1.000000  67.000000
2   2007-02-10      111        9.0      66  1.000000  66.000000
3   2007-01-13      139       10.0      83  0.880678  73.096278
4   2006-12-23      160       10.0      88  0.793033  69.786942
5   2006-11-09      204        9.0      52  0.636655  33.106077
6   2006-10-22      222        8.0      66  0.581946  38.408408
7   2006-09-29      245        9.0      70  0.518825  36.317752
8   2006-09-16      258       11.0      68  0.486226  33.063381
9   2006-08-30      275        8.0      72  0.446667  32.160051
10  2006-02-11      475        5.0      65  0.164591  10.698423
Run Code Online (Sandbox Code Playgroud)

选项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]]
Run Code Online (Sandbox Code Playgroud)

这也可以转换为数据框

df_new = pd.DataFrame(df_new, columns=df.columns)

[Out]:
     line_date daysago line_race rating        rw    wrating
0   2007-03-31      62      11.0     56       1.0       56.0
1   2007-03-10      83      11.0     67       1.0       67.0
2   2007-02-10     111       9.0     66       1.0       66.0
3   2007-01-13     139      10.0     83  0.880678  73.096278
4   2006-12-23     160      10.0     88  0.793033  69.786942
5   2006-11-09     204       9.0     52  0.636655  33.106077
6   2006-10-22     222       8.0     66  0.581946  38.408408
7   2006-09-29     245       9.0     70  0.518825  36.317752
8   2006-09-16     258      11.0     68  0.486226  33.063381
9   2006-08-30     275       8.0     72  0.446667  32.160051
10  2006-02-11     475       5.0     65  0.164591  10.698423
Run Code Online (Sandbox Code Playgroud)

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

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

       method                   time
0    Option 1 0.00000110000837594271
1  Option 2.1 0.00000139995245262980
2  Option 2.2 0.00000369996996596456
3  Option 2.3 0.00000160001218318939
4    Option 3 0.00000110000837594271
5    Option 4 0.00000120000913739204
6    Option 5 0.00000140001066029072
7    Option 6 0.00000159995397552848
8    Option 7 0.00000150001142174006
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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


笔记:


小智 8

一种有效且熊猫的方法是使用eq()方法:

df[~df.line_race.eq(0)]
Run Code Online (Sandbox Code Playgroud)

  • 为什么不是“df[df.line_race.ne(0)]”? (4认同)

Amr*_*ram 7

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

  df = df.drop(df[df['line_race']==0].index)
Run Code Online (Sandbox Code Playgroud)


小智 6

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

data = pd.read_excel('file.xlsx')
Run Code Online (Sandbox Code Playgroud)

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

data = data[data['expire/t'].notnull()]
print (date)
Run Code Online (Sandbox Code Playgroud)

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

data = data[data.expire ! = 0]
print (date)
Run Code Online (Sandbox Code Playgroud)


Rob*_*bvh 5

如果要基于列的多个值删除行,则可以使用:

df[(df.line_race != 0) & (df.line_race != 10)]
Run Code Online (Sandbox Code Playgroud)

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

  • 如果您有多个想要删除的值,即“drop = [0, 10]”,然后是“df[(df.line_race != drop)]”之类的内容,是否有更有效的方法来执行此操作 (2认同)
  • 好建议。```df[(df.line_race != drop)]``` 不起作用,但我想有可能做得更有效。我现在没有解决方案,但如果有人有,请立即告诉我们。 (2认同)
  • df[~(df["line_race"].isin([0,10]))] /sf/ask/2726127141/ -在水果列中找到的值 (2认同)

归档时间:

查看次数:

669929 次

最近记录:

6 年,3 月 前