Переназначение записей в столбце Pandas DataFrame - PullRequest
0 голосов
/ 24 ноября 2018

Моя цель состоит в том, чтобы условно проиндексировать фрейм данных и изменить значения в столбце для этих индексов.

Я намереваюсь просмотреть столбец 'A', чтобы найти записи = 'a' и обновить их столбец'B' со словом 'окей.

group = ['a']

df = pd.DataFrame({"A": [a,b,a,a,c], "B": [NaN,NaN,NaN,NaN,NaN]})
>>>df
   A    B
0  a  NaN
1  b  NaN
2  a  NaN
3  a  NaN
4  c  NaN

df[df['A'].apply(lambda x: x in group)]['B'].fillna('okay', inplace=True)

Это дает мне следующую ошибку:

SettingWithCopyWarning:

Значение пытается быть установлено для копиифрагмент из DataFrame

См. предостережения в документации: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy self._update_inplace (new_data)

Следуя документации (что я понял), я попробовал следующеевместо этого:

df[df['A'].apply(lambda x: x in group)].loc[:,'B'].fillna('okay', inplace=True)

Я не могу понять, почему переназначение «NaN» на «хорошо» не происходит на месте и как это можно исправить?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Если я правильно понимаю, вы просто хотите заменить значение для столбца в тех строках, соответствующих заданному условию (т. Е. Где A столбец принадлежит определенной группе, здесь с единственным значением 'a').Следующее должно сделать трюк:

import pandas as pd

group = ['a']

df = pd.DataFrame({"A": ['a','b','a','a','c'], "B": [None,None,None,None,None]})
print(df)
df.loc[df['A'].isin(group),'B'] = 'okay'
print(df)

Здесь мы используем фильтр .loc, который просто возвращает представление существующего фрейма данных.

СначалаАргумент (df['A'].isin(group)) фильтрует те строки, которые соответствуют заданному критерию.Обратите внимание, что вы можете использовать оператор равенства (==), но не оператор in и, следовательно, вместо него следует использовать .isin()).

Второй аргумент выбирает только столбец «B».Затем вы просто присваиваете желаемое значение (которое является константой).

Вот вывод:

   A     B
0  a  None
1  b  None
2  a  None
3  a  None
4  c  None
   A     B
0  a  okay
1  b  None
2  a  okay
3  a  okay
4  c  None

Если вы хотите заняться чем-то более сложным, вы можете сделать следующее:

import pandas as pd

group = ['a', 'b']

df = pd.DataFrame({"A": ['a','b','a','a','c'], "B": [None,None,None,None,None]})
df.loc[df['A'].isin(group),'B'] = "okay, it was " + df['A']+df['A']
print(df)

Что дает вам:

   A                B
0  a  okay, it was aa
1  b  okay, it was bb
2  a  okay, it was aa
3  a  okay, it was aa
4  c             None
0 голосов
/ 24 ноября 2018

Попробуйте это с лямбдой:

Первое решение:

>>> df
   A   B
0  a NaN
1  b NaN
2  a NaN
3  a NaN
4  c NaN

Использование lambda + map или apply ..

>>> df["B"] = df["A"].map(lambda x: "okay" if "a" in x else "NaN")
OR# df["B"] = df["A"].map(lambda x: "okay" if "a" in x else np.nan)
OR# df['B'] = df['A'].apply(lambda x: 'okay' if x == 'a' else np.nan)
>>> df
   A     B
0  a  okay
1  b   NaN
2  a  okay
3  a  okay
4  c   NaN

Второе решение:

>>> df
   A   B
0  a NaN
1  b NaN
2  a NaN
3  a NaN
4  c NaN

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

>>> frame = {'a': "okay"}
>>> df['B'] = df['A'].map(frame)
>>> df
   A     B
0  a  okay
1  b   NaN
2  a  okay
3  a  okay
4  c   NaN

Решение Третье:

Это уже опубликовано @d_kennetz, но я просто хочу объединиться в клуб, где вы также можете выполнить назначение для обоих столбцов (A & B) одним выстрелом:..

>>> df.loc[df.A == 'a', 'B'] = "okay"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...