Man*_*gia 3 python performance dataframe pandas
我想同步两个很长的数据帧,在这个用例中性能是关键。使用日期时间或时间戳按时间顺序对这两个数据帧进行索引(应该尽可能快地利用它)。
本例中提供了一种同步方式:
import pandas as pd
df1=pd.DataFrame({'A':[1,2,3,4,5,6], 'B':[1,5,3,4,5,7]}, index=pd.date_range('20140101 101501', freq='u', periods=6))
df2=pd.DataFrame({'D':[10,2,30,4,5,10], 'F':[1,5,3,4,5,70]}, index=pd.date_range('20140101 101501.000003', freq='u', periods=6))
# synch data frames
df3=df1.merge(df2, how='outer', right_index=True, left_index=True).fillna(method='ffill')
Run Code Online (Sandbox Code Playgroud)
我的问题是这是否是最有效的方法?如果有更快的方法来解决这个任务,我准备探索其他解决方案(例如使用 numpy 或 cython)。
谢谢
注意:时间戳通常不是等距间隔的(如上例所示),该方法也适用于这种情况
阅读答案后发表评论
我认为有很多用例既不对齐也不合并或加入帮助。关键是不要使用与 DB 相关的语义进行对齐(在我看来,这对于时间序列并不是那么相关)。对我来说,对齐意味着将系列 A 映射到 B 并有一种处理缺失值的方法(通常是采样和保持方法),对齐和连接会导致不想要的效果,例如由于连接而重复的几个时间戳。我仍然没有完美的解决方案,但似乎 np.searchsorted 可以提供帮助(它比使用多个调用来加入/对齐来完成我需要的要快得多)。到目前为止,我找不到熊猫的方法来做到这一点。
如何将 A 映射到 B 以便 B 使结果具有 A 和 B 的所有时间戳但没有重复(除了那些已经在 A 和 B 中的时间戳)?
另一个典型的用例是采样和保持同步,它可以通过如下有效的方式解决(同步 A 与 B,即为 A 中的每个时间戳取 B 中的相应值:
idx=np.searchsorted(B.index.values, A.index.values, side='right')-1
df=A.copy()
for i in B:
df[i]=B[i].ix[idx].values
Run Code Online (Sandbox Code Playgroud)
结果 df 包含 A 的相同索引和 B 中的同步值。
有没有一种有效的方法可以直接在熊猫中做这样的事情?
如果您需要同步,请使用align
,文档在此处。否则合并是一个不错的选择。
In [18]: N=100000
In [19]: df1=pd.DataFrame({'A':[1,2,3,4,5,6]*N, 'B':[1,5,3,4,5,7]*N}, index=pd.date_range('20140101 101501', freq='u', periods=6*N))
In [20]: df2=pd.DataFrame({'D':[10,2,30,4,5,10]*N, 'F':[1,5,3,4,5,70]*N}, index=pd.date_range('20140101 101501.000003', freq='u', periods=6*N))
In [21]: %timeit df1.merge(df2, how='outer', right_index=True, left_index=True).fillna(method='ffill')
10 loops, best of 3: 69.3 ms per loop
In [22]: %timeit df1.align(df2)
10 loops, best of 3: 36.5 ms per loop
In [24]: pd.set_option('max_rows',10)
In [25]: x, y = df1.align(df2)
In [26]: x
Out[26]:
A B D F
2014-01-01 10:15:01 1 1 NaN NaN
2014-01-01 10:15:01.000001 2 5 NaN NaN
2014-01-01 10:15:01.000002 3 3 NaN NaN
2014-01-01 10:15:01.000003 4 4 NaN NaN
2014-01-01 10:15:01.000004 5 5 NaN NaN
... .. .. .. ..
2014-01-01 10:15:01.599998 5 5 NaN NaN
2014-01-01 10:15:01.599999 6 7 NaN NaN
2014-01-01 10:15:01.600000 NaN NaN NaN NaN
2014-01-01 10:15:01.600001 NaN NaN NaN NaN
2014-01-01 10:15:01.600002 NaN NaN NaN NaN
[600003 rows x 4 columns]
In [27]: y
Out[27]:
A B D F
2014-01-01 10:15:01 NaN NaN NaN NaN
2014-01-01 10:15:01.000001 NaN NaN NaN NaN
2014-01-01 10:15:01.000002 NaN NaN NaN NaN
2014-01-01 10:15:01.000003 NaN NaN 10 1
2014-01-01 10:15:01.000004 NaN NaN 2 5
... .. .. .. ..
2014-01-01 10:15:01.599998 NaN NaN 2 5
2014-01-01 10:15:01.599999 NaN NaN 30 3
2014-01-01 10:15:01.600000 NaN NaN 4 4
2014-01-01 10:15:01.600001 NaN NaN 5 5
2014-01-01 10:15:01.600002 NaN NaN 10 70
[600003 rows x 4 columns]
Run Code Online (Sandbox Code Playgroud)