簡體   English   中英

Pandas 有條件地基於先前行計算列

[英]Pandas computed column based on previous rows conditionally

我有一個 pandas dataframe 像這樣:

                       date_open               date_closed       rate
id                                                                   
284113 2020-02-21 08:47:00+00:00 2020-03-04 08:55:28+00:00  11.588895
284114 2020-02-21 08:47:05+00:00 2020-03-04 08:55:22+00:00  11.588895
284115 2020-02-21 08:47:09+00:00 2020-03-04 08:55:13+00:00  11.588895
284116 2020-02-21 08:47:13+00:00 2020-03-04 08:55:07+00:00  11.559593
284117 2020-02-21 08:47:17+00:00 2020-03-04 08:53:11+00:00  11.530291
                          ...                       ...        ...
373069 2020-04-22 16:31:30+00:00 2020-04-30 17:25:55+00:00   3.481590
373070 2020-04-22 16:31:35+00:00 2020-04-30 17:25:23+00:00   3.510351
373071 2020-04-22 16:31:40+00:00 2020-04-30 17:24:25+00:00   3.529525
381966 2020-04-30 17:26:11+00:00 2020-04-30 17:28:43+00:00  -0.162813
381969 2020-04-30 17:26:49+00:00 2020-04-30 17:28:30+00:00  -0.181308
[131 rows x 3 columns]

我想添加一列,稱為efficiency

每行的efficiency應計算為rate s > 0 的總和除以當前行的date_closed <= date_open的行的rate s <= 0 的總和。

在 python 代碼(假設是字典列表而不是數據幀)中,我會達到這樣的結果:

for element in list_of_dicts:
   positive_rates = sum(list(filter(lambda x: x['rate'] > 0 and x['date_closed'] < element['date_open'], list_of_dicts)))
   negative_rates = sum(list(filter(lambda x: x['rate'] < 0 and x['date_closed'] < element['date_open'], list_of_dicts)))
   element['efficiency'] = postitive_rates / negative_rates

任何幫助,將不勝感激。 謝謝你。

我可以想到兩種方法來解決這個問題,一種在速度方面更好,另一種在 memory 方面更好。

第一個:創建一個新的列group ,進行外部merge ,使用mask過濾,按id分組,應用 lambda function 到分組 Z6A8064B5DF479455500553C47C50 並分配結果:

df['group'] = 1
df_merge = df.reset_index().merge(df[['date_closed', 'rate', 'group']],
                                  how='outer', on='group')

mask = df_merge['date_open'] >= df_merge['date_closed_y']

results = df_merge[mask].groupby('id')
          .apply(lambda df: df[df.rate_y > 0].rate_y.sum() /
                df[df.rate_y <= 0].rate_y.sum())

df['efficiency'] = results

第二種:只需apply function 應用於每一行:

df['efficiency'] = df.apply(lambda x:
     df[(df.date_closed <= x.date_open) & (df.rate > 0)].rate.sum()
     / df[(df.date_closed <= x.date_open) & (df.rate <= 0)].rate.sum(), axis=1)

暫無
暫無

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

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