Pandas устанавливает подмножество столбца в одно и то же значение dict

#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. Это небезопасно ~