【问题标题】:Changing pandas group column throws warning更改 pandas 组列会引发警告
【发布时间】:2015-07-31 16:44:51
【问题描述】:

在下面的代码中,我将 DataFrame 的点按 X 值分组到 bins 中。现在我想为 Y 列分配一个组 ID,但是 pandas 不断向我抛出 SettingWithCopyWarning 类型的警告。我做错了什么?

import numpy as np
import pandas as pd
d = np.random.random((10, 2))
d[:, 1] = 0
m = pd.DataFrame(d, columns=("x", "gid"))
dx = 0.2
grp = m.groupby(lambda i: int(m["x"][i] / dx))
gid = 1
for name, group in grp:
    group["gid"][:] = gid # This line crashes!
    gid += 1
print(m)

这是抛出的警告:

/usr/lib/python3.4/site-packages/pandas/core/series.py:677: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self._set_with(key, value)
sys:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

【问题讨论】:

  • 查看stackoverflow.com/a/16949498/1571826 以获得更优雅、更灵活的分箱方法。
  • 你用的是什么版本的熊猫?我也在运行 python 3.4,当我完全按原样运行代码时没有收到任何警告。
  • 在 python 3.4.3、pandas 0.16.1 和 numpy 1.9.2 中运行良好

标签: python pandas


【解决方案1】:

这里有两个问题。首先,你得到一个SettingWithCopyWarning,因为

group["gid"][:] = gid

使用“链式索引”。问题是有时group[...] 可能会返回 copy 而不是 groupview,因此需要进一步索引和修改副本,例如group[...][...] = gid may be useless since it only modifies the copy 而不是 groupSettingWithCopyWarning 是一个警告,在分配中检测到链式索引。这并不一定意味着出现任何问题。在您的情况下,group["gid"] 返回group 的视图,因此您的链式索引恰好成功地修改了group 本身。

尽管如此,推荐的做法是始终在执行分配时避免链式索引,因为预测链式索引是否会返回视图或副本并不总是容易的。

通常您可以使用.lociloc 来避免链式索引:

group.loc[:, "gid"] = gid 

第二个问题是即使我们避免链式索引,修改group也不会修改m

当你使用for-loop:

for name, group in grp:

Python 创建局部变量 namegroup 并将这些变量绑定到 grp 中的项目。但这些项目本身是m 部分的副本,而不是视图。所以修改这些副本不会影响m


您可以使用pd.Categorical,而不是使用groupby:

import numpy as np
import pandas as pd
np.random.seed(2015)
d = np.random.random((10, 2))
d[:, 1] = 0
m = pd.DataFrame(d, columns=("x", "gid"))
dx = 0.2
m['gid'] = pd.Categorical((m['x'] / dx).astype(int)).codes + 1

print(m)

产量

          x  gid
0  0.737595    3
1  0.884189    4
2  0.944676    4
3  0.063603    1
4  0.332454    2
5  0.003218    1
6  0.071058    1
7  0.289020    2
8  0.268896    2
9  0.258775    2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-29
    • 2019-06-16
    • 2012-07-18
    • 2021-10-30
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多