看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gr99123(备注: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 时间序列