ChatGPT解决这个技术问题 Extra ChatGPT

根据列值删除 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

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


t
tshauck

如果我理解正确,它应该很简单:

df = df[df.line_race != 0]

如果 df 很大,这会花费更多内存吗?或者,我可以就地做吗?
只需在具有 2M 行的 df 上运行它,它就运行得非常快。
@vfxGer 如果列中有空格,例如“line race”,那么您可以执行 df = df[df['line race'] != 0]
如果在该行的任何列中找到有问题的值,如果我们想删除整行,我们将如何修改此命令?
谢谢! Fwiw,对我来说这必须是 df=df[~df['DATE'].isin(['2015-10-30.1', '2015-11-30.1', '2015-12-31.1'])]
j
jezrael

但对于任何未来的绕过者,您可以提及 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 = df[df.columns[2].notnull()],但一种或另一种方式你需要能够以某种方式索引列。
df = df[df.line_race != 0] 删除行但也不重置索引。因此,当您在 df 中添加另一行时,它可能不会在最后添加。我建议在该操作之后重置索引 (df = df.reset_index(drop=True))
您永远不应该使用 == 运算符与 None 进行比较。 stackoverflow.com/questions/3257919/…
对于 None 值,您可以使用 is 代替 ==is not 代替 !=,就像在此示例中 df = df[df.line_race is not None] 将起作用
d
desmond

只是为了添加另一个解决方案,如果您使用新的 pandas 评估器特别有用,其他解决方案将替换原来的 pandas 并失去评估器

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

写索引和就地的目的是什么。谁能解释一下?
我认为如果有人最终使用索引访问器,我们也需要 .reset_index()
这确实是在数据搜索和删除中使用的正确答案。在此处添加更多解释。 df['line_race']==0].index -> 这将找到所有值为 0 的 'line_race' 列的行索引。inplace=True -> 这将修改原始数据帧 df。如果您不想修改原始数据帧,请删除 if(默认为 False)并将返回值存储在另一个数据帧中。
R
Robvh

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

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

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


如果您想要删除多个值,即 drop = [0, 10] 然后像 df[(df.line_race != drop)] 这样的值,是否有更有效的方法来执行此操作
好建议。 df[(df.line_race != drop)] 不起作用,但我想有可能更有效地做到这一点。我现在没有解决方案,但如果有人有,请让我们现在。
df[~(df["line_race"].isin([0,10]))] stackoverflow.com/questions/38944673/…
m
micstr

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

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

适合大型数据集或内存受限的解决方案。 +1
P
Phillip Cloud

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

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

更新: 现在 pandas 0.13 已经发布,另一种方法是 df.query('line_race != 0')


query 的好更新。它允许更丰富的选择标准(例如,类似集合的操作,如 df.query('variable in var_list'),其中 'var_list' 是所需值的列表)
如果列名中有一个空格,这将如何实现?
如果列名中有空格,query 就不是很有用。
我会避免在标题中使用类似 df = df.rename(columns=lambda x: x.strip().replace(' ','_')) 的空格
@Scientist1642 相同,但更简洁:df.columns = df.columns.str.replace(' ', '_')
z
zr0gravity7

如果有多个值和 str dtype

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

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]})
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(df, "str", ["b","c"])

   str  other
0   a   1
1   a   2
2   a   3
3   a   4

这是一个非常有用的小功能。谢谢。
我也喜欢这个。可能完全过时了,但添加了一个小参数,可以帮助我决定是选择还是删除它。如果您想将 df 一分为二,则非常方便:def filter_rows_by_values(df, col, values, true_or_false = False): return df[df[col].isin(values) == true_or_false]
您可以使用波浪号 ~ 反转运算符 df[~df[col].isin(values)]df[df[col].isin(values) == False] 替换为另一个否定条件。请参阅How can I obtain the element-wise logical NOT of a pandas Series?
h
h3h325

尽管如此,给出的答案是正确的,因为上面有人说您可以使用 df.query('line_race != 0') ,这取决于您的问题要快得多。强烈推荐。


如果您像我一样有很长的 DataFrame 变量名(而且,我敢猜测,每个人都与用于示例的 df 相比)特别有用,因为您只需编写一次。
为什么会更快?您正在获取一个字符串并对其进行评估,而不是普通表达式。
a
ashkangh

一种高效且流行的方法是使用 eq() 方法:

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

为什么不df[df.line_race.ne(0)]
A
Amruth Lakkavaram

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

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

T
Tufail Waris

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

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

G
Georgy

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

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

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

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

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

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

M
Muhammad Dyas Yaskur

只需为扩展所有列的 DataFrame 添加另一种方式:

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

例子:

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

j
juan escorcia

以防万一您需要删除该行,但该值可以位于不同的列中。就我而言,我使用的是百分比,所以我想删除任何列中值为 1 的行,因为这意味着它是 100%

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

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


w
wisbucky

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

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

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