一次性更改pandas DataFrame中多列的特定值

26
假设我有以下的DataFrame:
In [1]: df
Out[1]:
  apple banana cherry
0     0      3   good
1     1      4    bad
2     2      5   good

这个按预期工作:

In [2]: df['apple'][df.cherry == 'bad'] = np.nan
In [3]: df
Out[3]:
  apple banana cherry
0     0      3   good
1   NaN      4    bad
2     2      5   good

但这不会:

In [2]: df[['apple', 'banana']][df.cherry == 'bad'] = np.nan
In [3]: df
Out[3]:
  apple banana cherry
0     0      3   good
1     1      4    bad
2     2      5   good

为什么?我怎样才能在不写两行代码的情况下同时转换“apple”和“banana”值呢?

In [2]: df['apple'][df.cherry == 'bad'] = np.nan
In [3]: df['banana'][df.cherry == 'bad'] = np.nan
3个回答

39

你应该使用loc并且不要链接,做到这一点:

In [11]: df.loc[df.cherry == 'bad', ['apple', 'banana']] = np.nan

In [12]: df
Out[12]: 
   apple  banana cherry
0      0       3   good
1    NaN     NaN    bad
2      2       5   good

请查看有关返回视图与副本的文档,如果您链式赋值给副本(并被丢弃),但如果您在一个位置上执行,则 Pandas 会聪明地意识到您想要分配给原始数据。


1
将np.nan替换为另一个形状与df[['apple', 'banana']][df.cherry == 'bad']相同的数据框架是否容易扩展? - dermen
@dermen,它应该“只是工作”,但你可能会遇到对齐(在索引上)的问题......你可能需要分配 other_df.values。如果这种方法失败的话,也许值得提出另一个问题? - Andy Hayden
我在做这件事时遇到了麻烦,于是我发了这篇帖子。结果证明,将other_df.values赋值是正确的方法。 - dermen
有没有一种方法可以这样做,但将 NaN 分配给 apple 和 123 分配给 banana? - scrollout

5

这是因为df[['apple', 'banana']][df.cherry == 'bad'] = np.nan是在DataFrame的副本上进行赋值。可以尝试以下方法:

df.ix[df.cherry == 'bad', ['apple', 'banana']] = np.nan

3
иҜ·дёҚиҰҒеҶҚдҪҝз”Ёix APIпјҢиҖҢжҳҜж”№з”ЁlocжҲ–ilocгҖӮжңүе…іжӣҙеӨҡдҝЎжҒҜпјҢиҜ·жҹҘзңӢжӯӨWhat is meant by ".ix is deprecated" in Python Pandas?й“ҫжҺҘгҖӮ - WY Hsu

1
虽然这个问题很广泛,但回答似乎非常具体而不太灵活。这只是为了澄清...
df = pandas.DataFrame({'Test1' :[1,2,3,4,5], 'Test2': [3,4,5,6,7], 'Test3': [5,6,7,8,9]})

   Test1 Test2 Test3
0  1     3     5
1  2     4     6
2  3     5     7
3  4     6     8
4  5     7     9

# When the index or row you want to edit is known
df.loc[3, ['Test1', 'Test2', 'Test3'] = [10, 12, 14]

# When you don't know the index but can find it by looking in a column for a specific value

df.loc[df[df['Test1'] == 4].index[0], ['Test1', 'Test2', 'Test3']] = [10, 12, 14]

   Test1 Test2 Test3
0  1     3     5
1  2     4     6
2  3     5     7
3  10    12    14
4  5     7     9

这两种方法都允许您在一行代码中更改多个列的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接