我有兩個數據幀,每個數據幀包含一個date_from
和date_to
(指示數據的有效時間間隔),以及一個id
(指示哪些數據屬於一起)。在Python中,數據與日期間隔合併
from datetime import datetime
import pandas as pd
import numpy as np
df_a = pd.DataFrame({'id' : [1, 1, 1, 1, 2],
'date_from' : [datetime(2012, 1, 1), datetime(2012, 6, 1),
datetime(2013, 1, 1), datetime(2013, 6, 1),
datetime(2012, 1, 1)],
'date_to' : [datetime(2012, 6, 1), datetime(2013, 1, 1),
datetime(2013, 6, 1), datetime(2014, 1, 1),
datetime(2013, 1, 1)],
'data_a' : [1, 2, 3, 4, 5]})
df_b = pd.DataFrame({'id' : [1, 1],
'date_from' : [datetime(2012, 8, 1), datetime(2013, 4,1)],
'date_to' : [datetime(2013, 4,1), datetime(2013, 8, 1)],
'data_b' :['A','B']})
如果我做一個內部聯接使用date_from
的最大的爲新date_from
和最小的date_to
的「爲新date_to
這幫兩個表,並kepping只有那些條目,其中date_from < date_to
,我以正確的時間間隔得到想要的結果。
df = pd.merge(df_a, df_b, suffixes=['_a','_b'],on='id', how='inner')
df['date_from'] = df[['date_from_a', 'date_from_b']].max(axis=1)
df['date_to'] = df[['date_to_a', 'date_to_b']].min(axis=1)
df[['id', 'date_from', 'date_to', 'data_a','data_b']][(df['date_from']<df['date_to'])]
Out[2]:
id date_from date_to data_a data_b
2 1 2012-08-01 2013-01-01 2 A
4 1 2013-01-01 2013-04-01 3 A
5 1 2013-04-01 2013-06-01 3 B
7 1 2013-06-01 2013-08-01 4 B
萬歲!
但是,現在來了困難的部分,我不是真的想要一個內部連接,我想要一個左連接。重複上述步驟,左合併我得到
df = pd.merge(df_a, df_b, suffixes=['_a','_b'],on='id', how='left')
df['date_from'] = df[['date_from_a', 'date_from_b']].max(axis=1)
df['date_to'] = df[['date_to_a', 'date_to_b']].min(axis=1)
df[['id', 'date_from', 'date_to', 'data_a','data_b']][(df['date_from']<df['date_to'])]
Out[3]:
id date_from date_to data_a data_b
2 1 2012-08-01 2013-01-01 2 A
4 1 2013-01-01 2013-04-01 3 A
5 1 2013-04-01 2013-06-01 3 B
7 1 2013-06-01 2013-08-01 4 B
8 2 2012-01-01 2013-01-01 5 NaN
有什麼不對的這幅畫你說......好了的事情是我想從df_a
有還的情況下的數據,其中有沒有重疊的區間。基本上我想要這個結果
id date_from date_to data_a data_b
0 1 2012-01-01 2012-06-01 1 NaN
1 1 2012-06-01 2012-08-01 2 NaN
2 1 2012-08-01 2013-01-01 2 A
3 1 2013-01-01 2013-04-01 3 A
4 1 2013-04-01 2013-06-01 3 B
5 1 2013-06-01 2013-08-01 4 B
6 1 2013-08-01 2014-01-01 4 NaN
7 2 2012-01-01 2013-01-01 5 NaN
我不能用普通的sql產生這個結果。我知道的一種可能的解決方案是在數據前後填充df_b
空間隔。但這有它自己的問題,所以我想避免篡改df_b
。
所有幫助表示讚賞。謝謝。
嗨,我想我有一個解決方案,但在發佈之前,你可以確保你的「結果」數據框正確嗎?我認爲你錯過了一個額外的行,其中id == 1和data_b,A和B的位置在索引值3,4,5,6中,當它們應該位於索引位於[0,1, 3,6]。基本上沒有意義的是,在前兩個數據幀中,A和B在行2,4,5和7中,但在結果數據幀中,它們在3,4,5和6. – tompiler
您好!如果你有一個很棒的解決方案! :)不要擔心索引。我只是把東西放在那裏而沒有真正思考。 – mortysporty