我正在嘗試按 ID 和日期加入兩個資料框。但是,日期標準是 a.date<=b.date 并且如果 a.date 有很多結果,則取最大值(但仍然 <b.date)。我該怎么做?
Dataframe A (cumulative sales table)
ID| date | cumulative_sales
1 | 2020-01-01 | 10
1 | 2020-01-03 | 15
1 | 2021-01-02 | 20
Dataframe B
ID| date | cumulative_sales (up to this date, how much was purchased for a given ID?)
1 | 2020-05-01 | 15
在 SQL 中,我將通過 a.date<=b.date 進行連接,然后接下來我將進行 dense_rank() 并為每個 ID 獲取該磁區內的最大值。不知道如何用 Pandas 解決這個問題。有什么建議嗎?
uj5u.com熱心網友回復:
看起來你只是想要一個merge_asof:
dfA['date'] = pd.to_datetime(dfA['date'])
dfB['date'] = pd.to_datetime(dfB['date'])
out = pd.merge_asof(dfB.sort_values(by='date'),
dfA.sort_values(by='date'),
on='date', by='ID')
uj5u.com熱心網友回復:
這是一種解決您的問題的方法:
dfA = dfA.sort_values(['ID', 'date']).join(
dfB.set_index('ID'), on='ID', rsuffix='_b').query('date <= date_b').drop(
columns='date_b').groupby(['ID']).last().reset_index()
解釋:
- 排序
dfA方式ID, date - 用于
join加入dfBonID并將列從dfBin 帶入后綴_b - 用于
query僅保留dfA.date<=的行dfB.date - 使用
groupbyonID然后last選擇剩余值最高的行dfA.date(即,對于 eachdfA.date的 <=最高)dfB.dateID - 用于從索引級別
reset_index轉換ID回列標簽
完整的測驗代碼:
import pandas as pd
dfA = pd.DataFrame({'ID':[1,1,1,2,2,2], 'date':['2020-01-01','2020-01-03','2020-01-02','2020-01-01','2020-01-03','2020-01-02'], 'cumulative_sales':[10,15,20,30,40,50]})
dfB = pd.DataFrame({'ID':[1,2], 'date':['2020-05-01','2020-01-01'], 'cumulative_sales':[15,30]})
print(dfA)
print(dfB)
dfA = dfA.sort_values(['ID', 'date']).join(
dfB.set_index('ID'), on='ID', rsuffix='_b').query(
'date <= date_b').drop(columns='date_b').groupby(['ID']).last().reset_index()
print(dfA)
輸入:
dfA:
ID date cumulative_sales
0 1 2020-01-01 10
1 1 2020-01-03 15
2 1 2020-01-02 20
3 2 2020-01-01 30
4 2 2020-01-03 40
5 2 2020-01-02 50
dfB:
ID date cumulative_sales
0 1 2020-05-01 15
1 2 2020-01-01 30
輸出:
ID date cumulative_sales cumulative_sales_b
0 1 2020-01-03 15 15
1 2 2020-01-01 30 30
注意:我已經留cumulative_sales_b在原地,以備不時之需。如果不需要,可以通過替換來洗掉drop(columns='date_b')它drop(columns=['date_b', 'cumulative_sales_b'])。
更新:
為了好玩,如果你的 python 版本有海象運算子:=(也稱為“條件賦值”運算子),你可以這樣做而不是使用query:
dfA = (dfA := dfA.sort_values(['ID', 'date']).join(
dfB.set_index('ID'), on='ID', rsuffix='_b'))[dfA.date <= dfA.date_b].drop(
columns='date_b').groupby(['ID']).last().reset_index()
uj5u.com熱心網友回復:
我們可以做的merge
out = df1.merge(df2, on = 'ID', suffixes = ('','_x')).\
query('date<=date_x').sort_values('date').drop_duplicates('ID',keep='last')[df1.columns]
Out[272]:
ID date cumulative_sales
1 1 2020-01-03 15
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/482547.html
上一篇:在laravel中動態連接多個表
