簡體   English   中英

我想將 pandas DataFrame 中的兩列相乘並將結果添加到新列中

[英]I want to multiply two columns in a pandas DataFrame and add the result into a new column

我正在嘗試將 pandas Dataframe ( orders_df ) 中的兩個現有列相乘: Prices (股票收盤價)和Amount (庫存數量),並將計算添加到名為Value的新列中。 出於某種原因,當我運行這段代碼時,“ Value ”列下的所有行都是正數,而某些行應該是負數。 在 DataFrame 的“操作”列下,有七行帶有'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)

請讓我知道我做錯了什么!

我認為一個優雅的解決方案是使用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

此外,這應該是最快的解決方案。

您可以使用 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)

使用這些方法通常比 for 循環更快。

如果我們願意犧牲 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

現在我們已經消除了對if語句的需要。 使用DataFrame.apply() ,我們還取消了for循環。 正如海登所指出的,矢量化操作總是更快。

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

這個解決方案需要兩行代碼而不是一行代碼,但更容易閱讀。 我懷疑計算成本也相似。

由於這個問題再次出現,我認為一個很好的清潔方法是使用assign

該代碼非常具有表現力和自我描述性:

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

為了使事情變得整潔,我采用了海登的解決方案,但從中做了一個小功能。

def create_value(row):
    if row['Action'] == 'Sell':
        return row['Prices'] * row['Amount']
    else:
        return -row['Prices']*row['Amount']

這樣當我們想將函數應用到我們的數據幀時,我們可以做..

df['Value'] = df.apply(lambda row: create_value(row), axis=1)

...並且任何修改只需要發生在小函數本身中。

簡潔、易讀、整潔!

對我來說,這是最清晰、最直觀的:

values = []
for action in ['Sell','Buy']:
    amounts = orders_df['Amounts'][orders_df['Action'==action]].values
    if action == 'Sell':
        prices = orders_df['Prices'][orders_df['Action'==action]].values
    else:
        prices = -1*orders_df['Prices'][orders_df['Action'==action]].values
    values += list(amounts*prices)  
orders_df['Values'] = values

.values方法返回一個numpy array允許您輕松地按元素相乘,然后您可以通過“添加”累積生成一個列表。

來自 bmu 的好解決方案。 我認為將值放在括號內而不是放在括號外更具可讀性。

    df['Values'] = np.where(df.Action == 'Sell', 
                            df.Prices*df.Amount, 
                           -df.Prices*df.Amount)

使用一些內置函數的熊貓。

    df['Values'] = np.where(df.Action.eq('Sell'), 
                            df.Prices.mul(df.Amount), 
                           -df.Prices.mul(df.Amount))

首先,將PricesAmount列相乘。 如果條件為True ,則隨后使用mask取反值:

df.assign(
    Values=(df["Prices"] * df["Amount"]).mask(df["Action"] == "Buy", lambda x: -x)
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM