Вопрос: Вставить список в ячейки, соответствующие условиям столбца


Рассматривать df

   A  B  C
0  3  2  1
1  4  2  3
2  1  4  1
3  2  2  3

Я хочу добавить еще один столбец "D" так что D содержит разные списки, основанные на условиях "A", "B" а также "C"

   A  B  C  D
0  3  2  1  [1,0]
1  4  2  3  [1,0]
2  1  4  1  [0,2]
3  2  2  3  [2,0]

Мой фрагмент кода выглядит так:

df['D'] = 0
df['D'] = df['D'].astype(object)

df.loc[(df['A'] > 1) & (df['B'] > 1), "D"] = [1,0]
df.loc[(df['A'] == 1) , "D"] = [0,2]
df.loc[(df['A'] == 2) & (df['C'] != 0) , "D"] = [2,0]

Когда я пытаюсь запустить этот код, он выдает следующую ошибку:

ValueError: Must have equal len keys and value when setting with an iterable

Я преобразовал столбец в Object типа, как предложено Вот  но все еще с ошибкой.

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

Есть ли способ, которым я могу назначить списки вышеприведенным способом?


4


источник


Ответы:


Другим решением является создание Series заполнено list с shape для генерации length из df:

df.loc[(df['A'] > 1) & (df['B'] > 1), "D"] = pd.Series([[1,0]]*df.shape[0])
df.loc[(df['A'] == 1) , "D"] = pd.Series([[0,2]]*df.shape[0])
df.loc[(df['A'] == 2) & (df['C'] != 0) , "D"] = pd.Series([[2,0]]*df.shape[0])
print (df)
   A  B  C       D
0  3  2  1  [1, 0]
1  4  2  3  [1, 0]
2  1  4  1  [0, 2]
3  2  2  3  [2, 0]

3



Вот глупый способ сделать это

cond1 = df.A.gt(1) & df.B.gt(1)
cond2 = df.A.eq(1)
cond3 = df.A.eq(2) & df.C.ne(0)

df['D'] = cond3.map({True: [2, 0]}) \
  .combine_first(cond2.map({True: [0, 2]})) \
  .combine_first(cond1.map({True: [1, 0]})) \

df

enter image description here


3



отказ : Это мой собственный вопрос.

Оба ответа, предоставленные jezrael  а также piRSquared  Работа.

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

df.loc[(df['A'] > 1) & (df['B'] > 1), "D"] = '[1,0]'
df.loc[(df['A'] == 1) , "D"] = '[0,2]'
df.loc[(df['A'] == 2) & (df['C'] != 0) , "D"] = '[2,0]'

Это может быть неприменимо для всех, но я могу определенно подумать о ситуациях, когда этого будет достаточно.


1