目录
特殊连接
- merge_ordered()和merge_asof()是pandas的特殊连接。用于有序变量为键的合并,其参数中on、left_on、right_on、suffix和普通连接merge()的参数一致。
- 区别:merge_ordered()用于连接、插值和分组打包,而merge_asof()用于模糊连接。
merge_ordered()
构造两个表,按照表一的group进行分组,以time列为键外连接表2,并对结果进行排序,如果组内连接后有缺失值则用前一个元素填充。
import pandas as pd
#表一
df1 = pd.DataFrame({'time':pd.date_range('20230101','20230106'),'left_value':range(6),'group':list('aabbcc')})
df1
输出:
time | left_value | group | |
---|---|---|---|
0 | 2023-01-01 | 0 | a |
1 | 2023-01-02 | 1 | a |
2 | 2023-01-02 | 2 | b |
3 | 2023-01-04 | 3 | b |
4 | 2023-01-01 | 4 | c |
5 | 2023-01-03 | 5 | c |
df2 = pd.DataFrame({'time':pd.date_range('20230101','20230104'),'right_value':list('ABCD')})
df2 #表二
time | right_value | |
---|---|---|
0 | 2023-01-01 | A |
1 | 2023-01-02 | B |
2 | 2023-01-03 | C |
3 | 2023-01-04 | D |
使用分组策略进行操作:
df3 = df1.groupby('group').apply(
lambda x: x.merge(df2, on='time',how='outer').sort_values('time').ffill())
df3.group = df3.index.get_level_values('group')
df3 = df3.reset_index(drop=True)
df3
输出 :
time | left_value | group | right_value | |
---|---|---|---|---|
0 | 2023-01-01 | 0.0 | a | A |
1 | 2023-01-02 | 1.0 | a | B |
2 | 2023-01-03 | 1.0 | a | C |
3 | 2023-01-04 | 1.0 | a | D |
4 | 2023-01-01 | NaN | b | A |
5 | 2023-01-02 | 2.0 | b | B |
6 | 2023-01-03 | 2.0 | b | C |
7 | 2023-01-04 | 3.0 | b | D |
8 | 2023-01-01 | 4.0 | c | A |
9 | 2023-01-02 | 4.0 | c | B |
10 | 2023-01-03 | 5.0 | c | C |
11 | 2023-01-04 | 5.0 | c | D |
使用merge_orgered()进行相同操作。
pd.merge_ordered(df1,df2,on='time',how='outer',left_by='group',fill_method='ffill')
输出:
time | left_value | group | right_value | |
---|---|---|---|---|
0 | 2023-01-01 | 0.0 | a | A |
1 | 2023-01-02 | 1.0 | a | B |
2 | 2023-01-03 | 1.0 | a | C |
3 | 2023-01-04 | 1.0 | a | D |
4 | 2023-01-01 | NaN | b | A |
5 | 2023-01-02 | 2.0 | b | B |
6 | 2023-01-03 | 2.0 | b | C |
7 | 2023-01-04 | 3.0 | b | D |
8 | 2023-01-01 | 4.0 | c | A |
9 | 2023-01-02 | 4.0 | c | B |
10 | 2023-01-03 | 5.0 | c | C |
11 | 2023-01-04 | 5.0 | c | D |
merge_asof()
merge_asof()它是一个左连接函数,功能为键的模糊区配。
一个整点时间序列表与一个任意时间戳的时间序列记录表进行连接
df1 = pd.DataFrame({'time':pd.to_datetime(["20230101 0%d:00:00"%(i+1)for i in range(5)])})
df1
输出:
time | |
---|---|
0 | 2023-01-01 01:00:00 |
1 | 2023-01-01 02:00:00 |
2 | 2023-01-01 03:00:00 |
3 | 2023-01-01 04:00:00 |
4 | 2023-01-01 05:00:00 |
df2 = pd.DataFrame({'time':pd.to_datetime(['20230101 00:55:00','20230101 01:25:00',
'20230101 02:57:00','20230101 03:00:00','20230101 04:36:00']),'values':[1,2,3,4,5]})
df2
输出:
time | values | |
---|---|---|
0 | 2023-01-01 00:55:00 | 1 |
1 | 2023-01-01 01:25:00 | 2 |
2 | 2023-01-01 02:57:00 | 3 |
3 | 2023-01-01 03:00:00 | 4 |
4 | 2023-01-01 04:36:00 | 5 |
pd.merge_asof(df1,df2,on='time',direction='backward',tolerance=pd.Timedelta('60min'))
time | values | |
---|---|---|
0 | 2023-01-01 01:00:00 | 1 |
1 | 2023-01-01 02:00:00 | 2 |
2 | 2023-01-01 03:00:00 | 4 |
3 | 2023-01-01 04:00:00 | 4 |
4 | 2023-01-01 05:00:00 | 5 |
参数direction为backward,表示表一时间戳的数值 用表二不超过表一该时间戳的最多时间戳对应的值进行填充。例如表一中01:00:00 用表二00:57:00
参数direction还可以选择forward和nearest,分别表示使用不小于填充时间戳的时间戳的对应值填充以及使用时间戳最近的时间戳对应的值填充。参数tolerance表示前后时间戳不超过60分钟 ,可以设置为30,配合nearest使用。