這個問題實際上與我之前的問題非常相似(在這里給出:Splitting Dates in a Dataframe into 2 separate Dataframes),但稍微復雜一些,所以在嘗試了一個多小時后,我應該問一下。
Start我有一個資料框,其中兩列End是日期串列。我想做的是創建一個新的資料框,其中Start日期與最近的日期匹配End,并為每個匹配對在輸出的資料框中創建一個新行
基本上,如果列中有兩個值Start,那么只要End列中的日期在第一個日期之后和第二個日期之前(如下例中的 BBB 行所示),那么我想保留這些值輸出資料幀。此外,即使End列中沒有日期(如下例中的 EEE 行),我仍然想拆分它。Start如果和列中的一個或兩個End為空,則它們將保留在資料框中。
例如,對于下面的資料框:
Name Start End
AAA 2017-09-13
BBB 2021-11-20, 2022-06-04 2022-04-07
CCC 2022-09-29
DDD
EEE 2021-04-28, 2022-06-14
FFF 2021-06-25, 2022-06-19 2022-03-18, 2024-07-22
GGG 2020-10-23,2021-06-10, 2022-03-02 2021-03-06, 2022-01-04, 2024-08-15
最終的資料框看起來像這樣:
Name Start End
AAA 2016-09-13
BBB 2022-06-04 2022-04-07
CCC 2022-09-29
DDD
EEE 2022-06-14
FFF 2021-06-25 2022-03-18
FFF 2022-06-19 2024-07-22
GGG 2020-10-23 2021-03-06
GGG 2021-06-10 2022-01-04
GGG 2022-03-02 2024-08-15
我嘗試修改上面鏈接中給出的代碼,但我無法獲得我想要的輸出(不幸的是,我對 Python 很陌生......)。所以任何幫助將不勝感激,謝謝!
uj5u.com熱心網友回復:
它實際上與您的其他問題非常不同,而且不是那么簡單。
我會使用merge_asof, 用一個虛擬日期臨時替換 End 的 NaN 值的小技巧(這里我使用了 '1970-01-01'):
# pre-process the dataframe to split the strings into lists
df2 = df.set_index('Name').apply(lambda s: s.str.split(',\s*'))
out = (pd.merge_asof(
# explode End and fill NaN with 0 to get 1970-01-01
pd.to_datetime(df2['End'].explode().fillna(0))
.sort_values().reset_index(),
pd.to_datetime(df2['Start'].explode().dropna())
.sort_values().reset_index(),
by='Name', left_on='End', right_on='Start',
direction='nearest'
)
.sort_values(by='Name')
[['Name', 'Start', 'End']]
.assign(End=lambda d: d['End'].mask(d['End'].eq('1970-01-01')))
)
輸出:
Name Start End
0 AAA 2017-09-13 NaT
7 BBB 2022-06-04 2022-04-07
1 CCC 2022-09-29 NaT
2 DDD NaT NaT
3 EEE 2021-04-28 NaT
6 FFF 2022-06-19 2022-03-18
8 FFF 2022-06-19 2024-07-22
4 GGG 2021-06-10 2021-03-06
5 GGG 2022-03-02 2022-01-04
9 GGG 2022-03-02 2024-08-15
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/522557.html
