我想在pandas DataFrame中将两列相乘,并将结果添加到新列中

OAK*_*OAK 51 python python-2.7 pandas

我正在尝试将大熊猫Dataframe(orders_df)中的两个现有列相乘 - 价格(股票收盘价)和金额(库存数量),并将计算添加到名为"价值"的新列中.由于某些原因,当我运行此代码时,"值"列下的所有行都是正数,而某些行应为负数.在DataFrame的Action列下,有七行包含'Sell'字符串,七行包含'Buy'字符串.

for i in orders_df.Action:
 if i  == 'Sell':
  orders_df['Value'] = orders_df.Prices*orders_df.Amount
 elif i == 'Buy':
  orders_df['Value'] = -orders_df.Prices*orders_df.Amount)
Run Code Online (Sandbox Code Playgroud)

请让我知道我做错了什么!

bmu*_*bmu 71

我认为一个优雅的解决方案是使用该where方法(另见API docs):

In [37]: values = df.Prices * df.Amount

In [38]: df['Values'] = values.where(df.Action == 'Sell', other=-values)

In [39]: df
Out[39]: 
   Prices  Amount Action  Values
0       3      57   Sell     171
1      89      42   Sell    3738
2      45      70    Buy   -3150
3       6      43   Sell     258
4      60      47   Sell    2820
5      19      16    Buy    -304
6      56      89   Sell    4984
7       3      28    Buy     -84
8      56      69   Sell    3864
9      90      49    Buy   -4410
Run Code Online (Sandbox Code Playgroud)

此外,这应该是最快的解决方案.

  • 你能表明这回答了你的问题吗? (3认同)
  • 将此标记为您的答案,@OAK (2认同)

And*_*den 27

您可以使用DataFrame apply方法:

order_df['Value'] = order_df.apply(lambda row: (row['Prices']*row['Amount']
                                               if row['Action']=='Sell'
                                               else -row['Prices']*row['Amount']),
                                   axis=1)
Run Code Online (Sandbox Code Playgroud)

使用这些方法通常更快,而不是使用for循环.


Ama*_*man 18

如果我们愿意牺牲Hayden解决方案的简洁性,那么也可以这样做:

In [22]: orders_df['C'] = orders_df.Action.apply(
               lambda x: (1 if x == 'Sell' else -1))

In [23]: orders_df   # New column C represents the sign of the transaction
Out[23]:
   Prices  Amount Action  C
0       3      57   Sell  1
1      89      42   Sell  1
2      45      70    Buy -1
3       6      43   Sell  1
4      60      47   Sell  1
5      19      16    Buy -1
6      56      89   Sell  1
7       3      28    Buy -1
8      56      69   Sell  1
9      90      49    Buy -1
Run Code Online (Sandbox Code Playgroud)

现在我们已经消除了对if声明的需求.使用DataFrame.apply(),我们也取消了for循环.Hayden指出,矢量化操作总是更快.

In [24]: orders_df['Value'] = orders_df.Prices * orders_df.Amount * orders_df.C

In [25]: orders_df   # The resulting dataframe
Out[25]:
   Prices  Amount Action  C  Value
0       3      57   Sell  1    171
1      89      42   Sell  1   3738
2      45      70    Buy -1  -3150
3       6      43   Sell  1    258
4      60      47   Sell  1   2820
5      19      16    Buy -1   -304
6      56      89   Sell  1   4984
7       3      28    Buy -1    -84
8      56      69   Sell  1   3864
9      90      49    Buy -1  -4410
Run Code Online (Sandbox Code Playgroud)

此解决方案需要两行代码而不是一行,但更容易阅读.我怀疑计算成本也是相似的.

  • 只是为了挑剔,应该与符号一致,即如果您在左侧使用“df['column_name']”,则应该在右侧执行同样的操作,而不是“df.column_name”。 (2认同)

FLa*_*Lab 6

由于这个问题再次提出,我认为一个很好的清洁方法是使用assign.

代码非常富有表现力和自我描述:

df = df.assign(Value = lambda x: x.Prices * x.Amount * x.Action.replace({'Buy' : 1, 'Sell' : -1}))
Run Code Online (Sandbox Code Playgroud)