Новый столбец, использующий функцию apply для других столбцов в фрейме данных

У меня есть фрейм данных, где три столбца являются координатами данных ("H_x", "H_y" и "H_z"). Я хочу вычислить радиус-вектор данных и добавить его в качестве нового столбца в моем фрейме данных. Но у меня есть какая-то проблема с функцией применения панд. Мой код:

def radvec(x, y, z):
    rv=np.sqrt(x**2+y**2+z**2)
    return rv

halo_field['rh_field']=halo_field.apply(lambda row: radvec(row['H_x'], row['H_y'], row['H_z']), axis=1)

Я получаю ошибку:

group_sh.py:78: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas- 
docs/stable/indexing.html#indexing-view-versus-copy
halo_field['rh_field']=halo_field.apply(lambda row: radvec(row['H_x'], row['H_y'], row['H_z']), axis=1)

Я получаю столбец, который мне нужен, но я все еще путаюсь с этим сообщением об ошибке. Я знаю, что здесь есть подобные вопросы, но я не мог найти, как решить мою проблему. Я довольно новичок в питоне. Вы можете помочь?

Редактировать: halo_field это фрагмент другого фрейма данных:

halo_field = halo_res[halo_res.N_subs==1] 

1 ответ

Решение

Проблема в том, что вы работаете со срезом, который может быть неоднозначным:

halo_field = halo_res[halo_res.N_subs==1]

У вас есть два варианта:

Работа над копией

Вы можете явно скопировать ваш фрейм данных, чтобы избежать предупреждения и убедиться, что ваш оригинальный фрейм данных не затронут:

halo_field = halo_res[halo_res.N_subs==1].copy()
halo_field['rh_field'] = halo_field.apply(...)

Работа на исходном фрейме условно

использование pd.DataFrame.loc с булевой маской для обновления вашего исходного кадра данных:

mask = halo_res['N_subs'] == 1
halo_res.loc[mask, 'rh_field'] = halo_res.loc[mask, 'rh_field'].apply(...)

Не использовать apply

Как примечание, в любом сценарии вы можете избежать apply для вашей функции. Например:

halo_field['rh_field'] = (halo_field[['H_x', 'H_y', 'H_z']]**2).sum(1)**0.5
Другие вопросы по тегам