2015-05-19 3 views
0

В следующем фрагменте кода я группирую точки DataFrame по их значению X в бункеров. Теперь я хочу присвоить идентификатор группы столбцу Y, но панды продолжают бросать мне предупреждение типа SettingWithCopyWarning. Что я делаю не так?Изменение предупреждения столбцов группы pandas

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 
+0

Посмотрите http://stackoverflow.com/a/16949498/1571826 для более элегантный и гибкий подход к биннингам. –

+0

Какую версию панд вы используете? Я также запускаю python 3.4, и я не получил никакого предупреждения, когда я запускал ваш код точно так, как есть. – KCzar

+0

Прекрасно работает в python 3.4.3, pandas 0.16.1 и numpy 1.9.2 – EdChum

ответ

1

Есть две проблемы. Во-первых, вы получаете SettingWithCopyWarning потому что

group["gid"][:] = gid 

использует "прикован индексирование". Проблема в том, что иногда group[...] может возвращать копию вместо видgroup, и поэтому дальнейшая индексация и модификация копии, например. group[...][...] = gidmay be useless since it only modifies the copy и не group. SettingWithCopyWarning - это предупреждение, что при назначении была обнаружена цепочечная индексация. Это не обязательно означает, что все пошло не так. В вашем случае group["gid"] возвращает вид group, поэтому вашей цепочке индексирования удастся изменить сама group.

Тем не менее, рекомендуемая практика: всегда избегать привязки к цепочке при выполнении присвоений, поскольку предсказание не всегда легко предсказать, если цепочечная индексация вернет представление или копию.

Обычно вы можете избежать прикована индексации с помощью .loc или iloc:

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

Второго вопрос заключается в том, что даже если мы избегаем цепочечных индексаций, изменения group не изменяет m.

Когда вы используете for-loop:

for name, group in grp: 

Python создает локальные переменные name и group и связать эти переменные к элементам в grp. Но эти предметы сами являются копий, а не просмотров, частей m. Поэтому изменение этих копий не влияет на m.


Вместо использования GroupBy, вы могли бы использовать pd.Categorical:

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 
Смежные вопросы