将列表插入符合列条件的单元格

时间:2016-09-27 06:46:12

标签: python pandas

考虑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

我已根据建议here将列转换为Object类型,但仍有错误。

我可以推断的是,大熊猫正在尝试迭代列表中的元素,并将每个值分配给单元格,因为我试图将整个列表分配给符合条件的所有单元格。

有什么方法可以用上面的方式分配列表吗?

3 个答案:

答案 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

答案 1 :(得分:3)

另一个解决方案是创建Serieslist填充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]

答案 2 :(得分:1)

免责声明:这是我自己的问题。

jezraelpiRSquared提供的答案都有效。

我只想添加另一种方法,尽管与我在问题中发布的要求略有不同。您可以将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]'

这可能不适用于每个人的使用,但我绝对可以想到这样就足够的情况。