Pandas中的列表推导式

12

我举一个玩具示例,但它会帮助我理解我试图做的其他事情。假设我想要一个名为“optimal_fruit”的新数据框列,其值为apples * orange - bananas。

我可以像这样做到:

df2['optimal_fruit'] = df2['apples'] * df2['oranges'] - df2['bananas'] 


apples  oranges bananas optimal_fruit
1       6       11      -5
2       7       12      2
3       8       13      11
4       9       14      22
5       10      15      35

如果我尝试像这样做,会发生什么?我怎样才能在列表推导式中进行这个操作?

df2['optimal_fruit'] = [x * y - z for x in df2['apples'] for y in df2['oranges'] for z in df2['bananas']]

我遇到了一个错误:

ValueError: values的长度与index的长度不匹配

感谢大家一如既往的帮助!


1
可能是重复的问题https://stackoverflow.com/questions/58567199/memory-efficient-way-for-list-comprehension-of-pandas-dataframe-using-multiple-c/62064720#62064720 和 https://dev59.com/ua7la4cB1Zd3GeqPjc4N#62064822但这是第一个问题,所以可能重复的是这两个链接。 - questionto42
这个回答解决了你的问题吗?在Pandas数据框中选择多列 - questionto42
4个回答

27

实际上,您的列表推导语句是由3个嵌套循环组成的。在代码中:

l = []
for x in df2['apples']:
    for y in df2['oranges']:
        for z in df2['bananas']:
            l.append(x * y - z)

你的结果列表长度将是DataFrame长度的3次方倍数(5x5x5 = 125)。因此出现了错误。要解决这个问题,你需要相当于:

for x, y, z in zip(df2['apples'], df2['oranges'], df2['bananas']):
    l.extend([x * y - z])

关于列表推导式:
[x * y - z for x, y, z in zip(df2['apples'], df2['oranges'], df2['bananas'])]

4
你的新方法无法工作的原因是列表推导式产生的数据长度超出了数据框的索引数。一个快速的解决方法是:
[x * y - z for x,y,z in zip(df2['apples'], df2['oranges'], df2['bananas'])]

2

您可以在列表推导式中使用np.array()函数,将行的所有值作为列表获取。

以下代码解决了您的问题:

df2['optimal_fruit'] = [x[0] * x[1] - x[2] for x in np.array(df2)]

它将避免您在理解列表中键入每个列名的需要。

1
如果您不想为每个列重复df2:
[row[0][0]*row[0][1]-row[0][2] for row in zip(df2[['apples', 'oranges', 'bananas']].to_numpy())]

或者

def func(row):
    print(row[0]*row[1]-row[2])

[func(*row) for row in zip(df2[['apples', 'oranges', 'bananas']].to_numpy())]

更多阅读材料:

编辑:

请使用df.ilocdf.loc代替df[[...]],请参见在Pandas数据框中选择多个列


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接