#python #pandas #dataframe #dictionary #indexing
#python #pandas #фрейм данных #словарь #индексирование
Вопрос:
Если у меня есть фрейм данных, который выглядит следующим образом:
df = pd.DataFrame({'A': [1,1,1,2,2,2], 'B': [4,5,6,7,8,9]})
df['C'] = None
A B C
0 1 4 None
1 1 5 None
2 1 6 None
3 2 7 None
4 2 8 None
5 2 9 None
Как я могу установить подмножество C
с тем же значением словаря? Например, установить C
для всех строк, куда A==1
{'example': 5}
?
Похоже, это не работает:
df.loc[df['A']==1, 'C'] = {'example': 5}
Ответ №1:
np.where
В этом случае вы можете использовать:
df['C'] = np.where(df['A']==1, {'example': 5}, df['C'])
Вывод:
A B C
0 1 4 {'example': 5}
1 1 5 {'example': 5}
2 1 6 {'example': 5}
3 2 7 NaN
4 2 8 NaN
5 2 9 NaN
Обновление поскольку {'example': 5}
это итеративный объект, Pandas попытается развернуть его, когда вы назначите его столбцу, отсюда и ошибка несоответствия длины, если вы сделаете это напрямую. Чтобы присвоить весь столбец этому словарю, вам нужно обернуть его в другой итерируемый с той же длиной, что и df
:
df['C'] = [{'example':5} for _ in df.index]
Вывод:
A B C
0 1 4 {'example': 5}
1 1 5 {'example': 5}
2 1 6 {'example': 5}
3 2 7 {'example': 5}
4 2 8 {'example': 5}
5 2 9 {'example': 5}
Тем не менее, если это действительно не необходимо, по возможности следует избегать сложных объектов внутри фрейма данных Pandas.
Обновление 2: согласно комментарию БЕНА, а также отражено в обновлении
df['C'] = np.where(df['A']==1, {'example': 5}, df['C'])
может копировать один и тот же объект {'example':5}
во все допустимые строки, что может не соответствовать ожидаемому поведению. Итак, для этого что-то вроде:
df['C'] = [{'example':5} if a==1 else c for a,c in zip(df['A'], df['C'])]
создаст разные копии {'example':5'}
для соответствующих строк.
Комментарии:
1. Спасибо! Я думаю, что вы были первыми, но я не могу точно сказать 🙂
2. Кроме того, если вы не возражаете, как я могу установить для всего столбца C это значение dict? Примет этот ответ, как только он позволит
3. 2-й 1 более безопасен
Ответ №2:
Вы можете использовать np.where
:
df['C'] = np.where(df['A']==1, {'example': 5}, df['C'])
print(df)
С принтами:
A B C
0 1 4 {'example': 5}
1 1 5 {'example': 5}
2 1 6 {'example': 5}
3 2 7 None
4 2 8 None
5 2 9 None
Комментарии:
1. Это небезопасно ~