看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
时间序列数据是一个非常特别的数据类型,但也在我们现实中非常常见,本文将介绍如果将这些数据进行合并。
pd.merge_ordered
函数允许组合时间序列和其他有序数据。 特别是,它具有可选的fill_method 关键字来填充/插入丢失的数据:
left = pd.DataFrame({'k': ['K0', 'K1', 'K1', 'K2'],
'lv': [1, 2, 3, 4],
's': ['a', 'b', 'c', 'd']})
right = pd.DataFrame({'k': ['K1', 'K2', 'K4'],
'rv': [1, 2, 3]})
pd.merge_ordered(left, right, fill_method='ffill', left_by='s')
'''
k lv s rv
0 K0 1.0 a NaN
1 K1 1.0 a 1.0
2 K2 1.0 a 2.0
3 K4 1.0 a 3.0
4 K1 2.0 b 1.0
5 K2 2.0 b 2.0
6 K4 2.0 b 3.0
7 K1 3.0 c 1.0
8 K2 3.0 c 2.0
9 K4 3.0 c 3.0
10 K1 NaN d 1.0
11 K2 4.0 d 2.0
12 K4 4.0 d 3.0
'''
按照 s 列的顺序进行了排序,它也适用于时间类型的数据。
执行 asof 合并(as of 意为自……起;到…时候为止),这类似于左连接,只是我们匹配最近的关键点(on 参数指定)而不是相等的关键点。两个 DataFrame 必须按键排序。
语法为:
pd.merge_asof(left, right, on=None,
left_on=None, right_on=None,
left_index=False, right_index=False,
by=None, left_by=None, right_by=None,
suffixes=('_x', '_y'), tolerance=None,
allow_exact_matches=True,
direction='backward')
其中 on 参数的值代表的列名,必须在两个数据帧中都找到,必须对数据进行排序。此外,这必须是可以数字化的列,如 datetimelike(时间的各种类型), integer, float。必须要不给出参数 On 要么给出 left_on/right_on。
先上个例子:
left = pd.DataFrame({'a': [1, 5, 10], 'left_val': ['a', 'b', 'c']})
left
''' a left_val
0 1 a
1 5 b
2 10 c
'''
right = pd.DataFrame({'a': [1, 2, 3, 6, 7],
'right_val': [1, 2, 3, 6, 7]})
right
''' a right_val
0 1 1
1 2 2
2 3 3
3 6 6
4 7 7
'''
# 按 a 连接
pd.merge_asof(left, right, on='a')
''' a left_val right_val
0 1 a 1
1 5 b 3
2 10 c 7
'''
以上例中左表(基准表)与右表按共同的 a 列进行合并,在拼合 right_val 列时:
参数 direction 还可以取以下值:
参数 direction 的例子:
# 向前
pd.merge_asof(left, right, on="a", direction="forward")
'''
a left_val right_val
0 1 a 1.0
1 5 b 6.0
2 10 c NaN
'''
# 邻近
pd.merge_asof(left, right, on="a", direction="nearest")
'''
a left_val right_val
0 1 a 1
1 5 b 6
2 10 c 7
'''
pd.merge_asof(left, right, on='a', allow_exact_matches=False)
''' a left_val right_val
0 1 a NaN
1 5 b 3.0
2 10 c 7.0
'''
参数 allow_exact_matches 的意思是:
上例设置为 False,a=1 时,由于右表有同样的值,就不匹配了,给出了一个缺失值。
这个方法经常用于合并时间相关的数据,由于时间数据在合并时有细微的差别,不能完全匹配,就需要找到邻近的值使用。以下是时间相关的案例:
quotes
''' time ticker bid ask
0 2016-05-25 13:30:00.023 GOOG 720.50 720.93
1 2016-05-25 13:30:00.023 MSFT 51.95 51.96
2 2016-05-25 13:30:00.030 MSFT 51.97 51.98
3 2016-05-25 13:30:00.041 MSFT 51.99 52.00
4 2016-05-25 13:30:00.048 GOOG 720.50 720.93
5 2016-05-25 13:30:00.049 AAPL 97.99 98.01
6 2016-05-25 13:30:00.072 GOOG 720.50 720.88
7 2016-05-25 13:30:00.075 MSFT 52.01 52.03'''
trades
''' time ticker price quantity
0 2016-05-25 13:30:00.023 MSFT 51.95 75
1 2016-05-25 13:30:00.038 MSFT 51.95 155
2 2016-05-25 13:30:00.048 GOOG 720.77 100
3 2016-05-25 13:30:00.048 GOOG 720.92 100
4 2016-05-25 13:30:00.048 AAPL 98.00 100'''
pd.merge_asof(trades, quotes,
on='time',
by='ticker')
''' time ticker price quantity bid ask
0 2016-05-25 13:30:00.023 MSFT 51.95 75 51.95 51.96
1 2016-05-25 13:30:00.038 MSFT 51.95 155 51.97 51.98
2 2016-05-25 13:30:00.048 GOOG 720.77 100 720.50 720.93
3 2016-05-25 13:30:00.048 GOOG 720.92 100 720.50 720.93
4 2016-05-25 13:30:00.048 AAPL 98.00 100 NaN NaN'''
pd.merge_asof(trades, quotes,
on='time',
by='ticker',
tolerance=pd.Timedelta('2ms'))
''' time ticker price quantity bid ask
0 2016-05-25 13:30:00.023 MSFT 51.95 75 51.95 51.96
1 2016-05-25 13:30:00.038 MSFT 51.95 155 NaN NaN
2 2016-05-25 13:30:00.048 GOOG 720.77 100 720.50 720.93
3 2016-05-25 13:30:00.048 GOOG 720.92 100 720.50 720.93
4 2016-05-25 13:30:00.048 AAPL 98.00 100 NaN NaN'''
pd.merge_asof(trades, quotes,
on='time',
by='ticker',
tolerance=pd.Timedelta('10ms'),
allow_exact_matches=False)
''' time ticker price quantity bid ask
0 2016-05-25 13:30:00.023 MSFT 51.95 75 NaN NaN
1 2016-05-25 13:30:00.038 MSFT 51.95 155 51.97 51.98
2 2016-05-25 13:30:00.048 GOOG 720.77 100 NaN NaN
3 2016-05-25 13:30:00.048 GOOG 720.92 100 NaN NaN
4 2016-05-25 13:30:00.048 AAPL 98.00 100 NaN NaN'''
tolerance 参数可传入一个时长数据(Timedelta,在非时间数据情况下可以传入一个 int),表示能够容易的差距范围,必须与合并索引兼容。
更新时间:2021-12-17 22:37:22 标签:pandas 时间序列