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)
此外,这应该是最快的解决方案.
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)
此解决方案需要两行代码而不是一行,但更容易阅读.我怀疑计算成本也是相似的.
由于这个问题再次提出,我认为一个很好的清洁方法是使用assign.
代码非常富有表现力和自我描述:
df = df.assign(Value = lambda x: x.Prices * x.Amount * x.Action.replace({'Buy' : 1, 'Sell' : -1}))
Run Code Online (Sandbox Code Playgroud)