[英]Merge two dataframes in pandas with common info as columns or as cells
我在 python 中有兩個 pandas dateframes,df_main 和 df_aux。
df_main 是一個收集事件的表,其中包含事件發生的日期時間和提供編碼位置的“描述”列。 它具有以下結構:
日期 | 描述 |
---|---|
2022-01-01 13:45:23 | 一種 |
2022-01-01 14:22:00 | C |
2022-01-01 16:15:33 | 丁 |
2022-01-01 16:21:22 | 乙 |
2022-01-02 13:21:56 | 乙 |
2022-01-02 14:45:41 | 乙 |
2022-01-02 15:11:34 | C |
df_aux 是一個表格,它給出了在每個位置(A、B、C、D)發生的其他事件的數量(例如,人們在 Initial_Date 和 Final_Date 內走過),粒度為 1 小時。 df_aux的結構如下:
初始日期 | 最終日期 | 一種 | 乙 | C | 丁 |
---|---|---|---|---|---|
2022-01-01 12:00:00 | 2022-01-01 12:59:59 | 2個 | 0 | 1個 | 2個 |
2022-01-01 13:00:00 | 2022-01-01 13:59:59 | 3個 | 2個 | 4個 | 5個 |
2022-01-01 14:00:00 | 2022-01-01 14:59:59 | 2個 | 2個 | 7 | 0 |
2022-01-01 15:00:00 | 2022-01-01 15:59:59 | 5個 | 2個 | 2個 | 0 |
2022-01-02 12:00:00 | 2022-01-02 12:59:59 | 1個 | 1個 | 0 | 3個 |
2022-01-02 13:00:00 | 2022-01-02 13:59:59 | 5個 | 5個 | 0 | 3個 |
2022-01-02 14:00:00 | 2022-01-02 14:59:59 | 2個 | 3個 | 2個 | 1個 |
2022-01-02 15:00:00 | 2022-01-02 15:59:59 | 3個 | 4個 | 1個 | 0 |
所以我的問題是我需要在 df_main 中添加一個新列來說明事件發生前一小時內路過的人數。 例如,在發生在 13:45:23h 的第一個事件中,我們將轉到 df_aux 並查找前一小時 (12:45:23),這是第一行,因為 12:45:23 是在 12:00:00 和 12:59:59 之間。 在該時間范圍內,A 列的值為 2,因此我們將向 df_main 添加一個新列“People_prev_hour”,取值 2。
按照相同的邏輯,完整的 df_main 將是,
日期 | 描述 | People_prev_hour |
---|---|---|
2022-01-01 13:45:23 | 一種 | 2個 |
2022-01-01 14:22:00 | C | 4個 |
2022-01-01 16:15:33 | 丁 | 0 |
2022-01-01 16:21:22 | 乙 | 鈉鹽 |
2022-01-02 13:21:56 | 乙 | 1個 |
2022-01-02 14:45:41 | 乙 | 5個 |
2022-01-02 15:11:34 | F | 鈉鹽 |
兩個 dfs 之間的日期時間將始終是完整的,但描述列可能不會。 如在完整的 df_main 中所見,兩行具有描述值 E 和 F,它們不在 df_aux 中。 因此,在這些情況下,必須存在 NaN。
我想不出將這兩個 df 合並到所需輸出的方法,因為 pd.merge 使用公共列,而且我無法對 pd.melt 或 pd.pivot 做任何事情。 任何幫助深表感謝!
采用:
df1 = pd.merge_asof(df_main,
df_aux.assign(Initial_Date = df_aux['Initial_Date'] + pd.Timedelta(1, 'hour')),
left_on='Date',
right_on='Initial_Date')
idx, cols = pd.factorize(df1['Description'])
df_main['People_prev_hour'] = (df1.reindex(cols, axis=1).to_numpy() [np.arange(len(df1)), idx])
print (df_main)
Date Description People_prev_hour
0 2022-01-01 13:45:23 A 2.0
1 2022-01-01 14:22:00 C 4.0
2 2022-01-01 16:15:33 D 0.0
3 2022-01-01 16:21:22 E NaN
4 2022-01-02 13:21:56 B 1.0
5 2022-01-02 14:45:41 B 5.0
6 2022-01-02 15:11:34 C 2.0
IntervalIndex
的另一個想法:
s = pd.IntervalIndex.from_arrays(df_aux.Initial_Date + pd.Timedelta(1, 'hour'),
df_aux.Final_Date + pd.Timedelta(1, 'hour'), 'both')
df1 = df_aux.set_index(s).loc[df_main.Date]
print (df1)
Initial_Date \
[2022-01-01 13:00:00, 2022-01-01 13:59:59] 2022-01-01 12:00:00
[2022-01-01 14:00:00, 2022-01-01 14:59:59] 2022-01-01 13:00:00
[2022-01-01 16:00:00, 2022-01-01 16:59:59] 2022-01-01 15:00:00
[2022-01-01 16:00:00, 2022-01-01 16:59:59] 2022-01-01 15:00:00
[2022-01-02 13:00:00, 2022-01-02 13:59:59] 2022-01-02 12:00:00
[2022-01-02 14:00:00, 2022-01-02 14:59:59] 2022-01-02 13:00:00
[2022-01-02 15:00:00, 2022-01-02 15:59:59] 2022-01-02 14:00:00
Final_Date A B C D
[2022-01-01 13:00:00, 2022-01-01 13:59:59] 2022-01-01 12:59:59 2 0 1 2
[2022-01-01 14:00:00, 2022-01-01 14:59:59] 2022-01-01 13:59:59 3 2 4 5
[2022-01-01 16:00:00, 2022-01-01 16:59:59] 2022-01-01 15:59:59 5 2 2 0
[2022-01-01 16:00:00, 2022-01-01 16:59:59] 2022-01-01 15:59:59 5 2 2 0
[2022-01-02 13:00:00, 2022-01-02 13:59:59] 2022-01-02 12:59:59 1 1 0 3
[2022-01-02 14:00:00, 2022-01-02 14:59:59] 2022-01-02 13:59:59 5 5 0 3
[2022-01-02 15:00:00, 2022-01-02 15:59:59] 2022-01-02 14:59:59 2 3 2 1
idx, cols = pd.factorize(df_main['Description'])
df_main['People_prev_hour'] = (df1.reindex(cols, axis=1).to_numpy() [np.arange(len(df1)), idx])
print (df_main)
Date Description People_prev_hour
0 2022-01-01 13:45:23 A 2.0
1 2022-01-01 14:22:00 C 4.0
2 2022-01-01 16:15:33 D 0.0
3 2022-01-01 16:21:22 E NaN
4 2022-01-02 13:21:56 B 1.0
5 2022-01-02 14:45:41 B 5.0
6 2022-01-02 15:11:34 C 2.0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.