我给出了一个玩具示例,但它会帮助我理解我正在尝试做的其他事情。我们想说我想在数据框中添加一个新列' optimal_fruit'那是苹果*橙子 - 香蕉。
我可以做这样的事情来获得它。
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:值的长度与索引的长度
不匹配一如既往,非常感谢你的帮助!
答案 0 :(得分:10)
基本上你的列表理解语句是一组3个嵌套循环。在代码中:
l = []
for x in df2['apples']:
for y in df2['oranges']:
for z in df2['bananas']:
l.extend([x * y - z])
结果列表的长度将是DataFrame长度的3倍。因此错误。要修复,您需要等效于:
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'])]
答案 1 :(得分:3)
您的新方法无法工作的原因是列表推导产生的数据长于数据帧中的索引数。快速解决这个问题就像:
[x * y - z for x,y,z in zip(df2['apples'], df2['oranges'], df2['bananas'])]
答案 2 :(得分:0)
如果您不想为每列重复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.iloc和df.loc而不是df [[...]],请参见Selecting multiple columns in a pandas dataframe
答案 3 :(得分:0)
您可以使用理解列表中的np.array()
函数以列表的形式获取该行的所有值。
以下代码解决了您的问题:
df2['optimal_fruit'] = [x[0] * x[1] - x[2] for x in np.array(df2)]
这将避免在理解列表中键入每个列名称。