我有两个数据帧需要一个复杂的连接操作,这超出了熊猫的合并能力。
数据帧1是一组帐户记录,其中有多个guid映射到单个rid。但是,它们保证有不重叠的开始和结束日期。
df1 = pd.DataFrame({'StartDate': pd.date_range('2010-01-01', periods=4, freq='5D'),
'EndDate': pd.date_range('2010-01-04', periods=4, freq='5D'),
'rid': ['A', 'A', 'A', 'B'],
'GUID': ['1', '2', '3', '4']})
>>> df1
StartDate EndDate rid GUID
0 2010-01-01 2010-01-04 A 1
1 2010-01-06 2010-01-09 A 2
2 2010-01-11 2010-01-14 A 3
3 2010-01-01 2010-01-19 B 4
数据帧2是一组按日期和RID划分的事务。
rid_list = [random.choice(("A", "B")) for x in range(50)]
df2 = pd.DataFrame(dict(values=np.random.randn(
50), date_time=pd.date_range('2010-01-01', periods=50, freq='D'), rid=rid_list))
>>> df2.head()
values date_time rid
0 -0.214056 2010-01-01 A
1 0.168259 2010-01-02 A
2 -1.214433 2010-01-03 B
3 0.314966 2010-01-04 A
4 1.953925 2010-01-05 B
5 -0.027883 2010-01-06 A
6 -0.207795 2010-01-07 B
7 0.530119 2010-01-08 A
8 -0.297716 2010-01-09 B
9 2.080151 2010-01-10 B
我需要将正确的guid与每一个guid关联起来,但无法与pandas关联。例如,正确联接的df1和df2的第一行的guid为1,因为它是并且在guid 1的时间范围内发生。
>>> df2.head()
values date_time rid GUID
0 -0.214056 2010-01-01 A 1
1 0.168259 2010-01-02 A 1
2 -1.214433 2010-01-03 B 4
3 0.314966 2010-01-04 A 1
4 1.953925 2010-01-05 B 4
5 -0.027883 2010-01-06 A 2
6 -0.207795 2010-01-07 B 4
7 0.530119 2010-01-08 A 2
8 -0.297716 2010-01-09 B 4
9 2.080151 2010-01-10 B 4
从这条线,
Merging dataframes based on date range
,我认为一个np.分段解决方案会奏效:
df2['GUID'] = np.piecewise(np.zeros(len(df2)), [(df2.date_time.values >= start_date) & (
df2.date_time.values <= end_date) & (df2.rid == rid) for start_date, end_date, rid in zip(df1.StartDate.values, df1.EndDate.values, df1.rid.values)], df1.GUID.values)
不幸的是,这将返回:
ValueError: with 1 condition(s), either 1 or 2 functions are expected
你知道怎么做吗?我以前使用pandasql来处理这个问题,但是在它周围遇到了可伸缩性问题。