Pandas替换特定列的值。

23

我意识到这两个类似的问题:

Pandas替换值

Pandas:在数据框中替换列值

我使用了一种不同的方法来替换值,我认为它应该是最简洁的方法。但它不起作用。我知道如何解决它,但我想了解为什么它不起作用:

In [108]: df=pd.DataFrame([[1, 2, 8],[3, 4, 8], [5, 1, 8]], columns=['A', 'B', 'C']) 

In [109]: df
Out[109]: 
   A  B  C
0  1  2  8
1  3  4  8
2  5  1  8

In [110]: df.loc[:, ['A', 'B']].replace([1, 3, 2], [3, 6, 7], inplace=True)

In [111]: df
Out[111]: 
   A  B  C
0  1  2  8
1  3  4  8
2  5  1  8

In [112]: df.loc[:, 'A'].replace([1, 3, 2], [3, 6, 7], inplace=True)

In [113]: df
Out[113]: 
   A  B  C
0  3  2  8
1  6  4  8
2  5  1  8

如果我只切割一个列 In [112],它与切割多个列 In [110] 的结果不同。根据我对 .loc 方法的理解,它返回的是视图而不是副本。在我的逻辑中,这意味着对切片进行原地更改应该会改变整个 DataFrame。这就是在代码行 In [110] 发生的事情。


你的 df 构造函数中有一个拼写错误,你需要传递 columns=['A','B','C'] - EdChum
我认为这是因为您的语法有误:df.loc[:, 'A': 'B'].replace([1, 3, 2], [3, 6, 7], inplace=True) 是可以工作的,但似乎由于某种原因会引发“正在尝试在 DataFrame 的切片副本上设置值”的警告。 - EdChum
其实我认为这是一个bug,现在应该按照df.loc[:, 'A': 'B'].replace的方式工作,因为它与df.loc[:, ['A', 'B']].replace相同。 - EdChum
非常感谢!由于我想将此应用于多个分隔的列,因此您的切片解决方案对我无效。我将使用 df.loc[:, ['A', 'B']] = df.loc[:, ['A', 'B']].replace([1, 3, 2], [3, 6, 7]) 并将其写入Pandas错误报告。 - mcocdawc
2个回答

37

这是其中一位开发者的回答:https://github.com/pydata/pandas/issues/11984

理想情况下应该显示一个SettingWithCopyWarning警告,但我认为这很难检测到。

您永远不应该进行此类链式inplace设置,这仅仅是不良做法。

惯用写法是:

In [7]: df[['A','B']] = df[['A','B']].replace([1, 3, 2], [3, 6, 7])

In [8]: df
Out[8]: 
   A  B  C
0  3  7  8
1  6  4  8
2  5  3  8

你也可以使用df.loc[:,['A','B']],但与上述方法相比,上述方法更加清晰易懂。


3
to_rep = dict(zip([1, 3, 2],[3, 6, 7]))
df.replace({'A':to_rep, 'B':to_rep}, inplace = True)

这将返回:
   A  B  C
0  3  7  8
1  6  4  8
2  5  3  8

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