更改pandas组列会抛出警告

时间:2015-05-19 17:49:00

标签: python pandas

在下面的代码中,我将DataFrame的点的X值分组到 bins 中。现在我想将一个组ID分配给Y列,但是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

1 个答案:

答案 0 :(得分:1)

这里有两个问题。首先,您获得了SettingWithCopyWarning,因为

group["gid"][:] = gid

使用“链式索引”。问题是,有时group[...]可能会返回副本而不是group视图,因此进一步索引和修改副本,例如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
相关问题