Pandas DataFrame concat vs append
Posted
技术标签:
【中文标题】Pandas DataFrame concat vs append【英文标题】: 【发布时间】:2013-03-26 23:46:03 【问题描述】:我有一个包含 4 个熊猫数据框的列表,其中包含我想要合并到单个数据框中的一天的刻度数据。我无法理解 concat 在我的时间戳上的行为。请参阅下面的详细信息:
data
[<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 35228 entries, 2013-03-28 00:00:07.089000+02:00 to 2013-03-28 18:59:20.357000+02:00
Data columns:
Price 4040 non-null values
Volume 4040 non-null values
BidQty 35228 non-null values
BidPrice 35228 non-null values
AskPrice 35228 non-null values
AskQty 35228 non-null values
dtypes: float64(6),
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 33088 entries, 2013-04-01 00:03:17.047000+02:00 to 2013-04-01 18:59:58.175000+02:00
Data columns:
Price 3969 non-null values
Volume 3969 non-null values
BidQty 33088 non-null values
BidPrice 33088 non-null values
AskPrice 33088 non-null values
AskQty 33088 non-null values
dtypes: float64(6),
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 50740 entries, 2013-04-02 00:03:27.470000+02:00 to 2013-04-02 18:59:58.172000+02:00
Data columns:
Price 7326 non-null values
Volume 7326 non-null values
BidQty 50740 non-null values
BidPrice 50740 non-null values
AskPrice 50740 non-null values
AskQty 50740 non-null values
dtypes: float64(6),
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 60799 entries, 2013-04-03 00:03:06.994000+02:00 to 2013-04-03 18:59:58.180000+02:00
Data columns:
Price 8258 non-null values
Volume 8258 non-null values
BidQty 60799 non-null values
BidPrice 60799 non-null values
AskPrice 60799 non-null values
AskQty 60799 non-null values
dtypes: float64(6)]
使用append
我得到:
pd.DataFrame().append(data)
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 179855 entries, 2013-03-28 00:00:07.089000+02:00 to 2013-04-03 18:59:58.180000+02:00
Data columns:
AskPrice 179855 non-null values
AskQty 179855 non-null values
BidPrice 179855 non-null values
BidQty 179855 non-null values
Price 23593 non-null values
Volume 23593 non-null values
dtypes: float64(6)
使用concat
我得到:
pd.concat(data)
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 179855 entries, 2013-03-27 22:00:07.089000+02:00 to 2013-04-03 16:59:58.180000+02:00
Data columns:
Price 23593 non-null values
Volume 23593 non-null values
BidQty 179855 non-null values
BidPrice 179855 non-null values
AskPrice 179855 non-null values
AskQty 179855 non-null values
dtypes: float64(6)
注意使用concat
时索引如何变化。为什么会发生这种情况,我将如何使用concat
来重现使用append
获得的结果? (因为concat
看起来要快得多;每循环 24.6 毫秒 vs 每循环 3.02 秒)
【问题讨论】:
【参考方案1】:Pandas concat vs append vs join vs merge
Concat 提供了基于轴(所有行或所有列)连接的灵活性
Append是concat的具体情况(axis=0, join='outer')
Join是基于索引(由set_index设置)变量=['left','right','inner','outer']
合并基于两个数据帧中的每一个的任何特定列,这些列是诸如“left_on”、“right_on”、“on”之类的变量
【讨论】:
【参考方案2】:所以你在做什么是 append 和 concat 几乎等效。不同之处在于空的 DataFrame。出于某种原因,这会导致大幅放缓,不确定究竟是为什么,将不得不看看某个点。下面是对您所做的基本操作的再现。
我几乎总是使用 concat(尽管在这种情况下它们是等价的,除了空框架); 如果你不使用空框架,它们将是相同的速度。
In [17]: df1 = pd.DataFrame(dict(A = range(10000)),index=pd.date_range('20130101',periods=10000,freq='s'))
In [18]: df1
Out[18]:
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 10000 entries, 2013-01-01 00:00:00 to 2013-01-01 02:46:39
Freq: S
Data columns (total 1 columns):
A 10000 non-null values
dtypes: int64(1)
In [19]: df4 = pd.DataFrame()
The concat
In [20]: %timeit pd.concat([df1,df2,df3])
1000 loops, best of 3: 270 us per loop
This is equavalent of your append
In [21]: %timeit pd.concat([df4,df1,df2,df3])
10 loops, best of
3: 56.8 ms per loop
【讨论】:
感谢您的回复,这解释了计算时间的差异。关于为什么我的索引突然随机变化的任何指示? hmm 看起来像是时区问题,将提交错误报告 非常感谢!感谢您的帮助。【参考方案3】:我已经实施了一个小型基准测试(请查找code on Gist)来评估熊猫的concat
和append
。我更新了代码 sn-p 和ssk08
评论后的结果 - 非常感谢!
基准测试在 Mac OS X 10.13 系统上运行,使用 Python 3.6.2 和 pandas 0.20.3。
+--------+---------------------------------+------ ---------------+ | |忽略索引=假 |忽略索引=真 | +--------+---------------------------------+------ ---------------+ |尺寸 |附加 |连接 |追加/连接 |附加 |连接 |追加/连接 | +--------+--------+--------+----------------+------ --+--------+---------------+ |小| 0.4635 | 0.4891 | 94.77 % | 0.4056 | 0.3314 | 122.39 % | +--------+--------+--------+----------------+------ --+--------+---------------+ |中 | 0.5532 | 0.6617 | 83.60 % | 0.3605 | 0.3521 | 102.37 % | +--------+--------+--------+----------------+------ --+--------+---------------+ |大| 0.9558 | 0.9442 | 101.22 % | 0.6670 | 0.6749 | 98.84 % | +--------+--------+--------+----------------+------ --+--------+---------------+使用ignore_index=False
append
稍快,使用ignore_index=True
concat
稍快。
tl;博士
concat
和 append
之间没有显着差异。
【讨论】:
其实这是一个错误的评价。您的 concat 代码 (pd.concat([df_small], ignore_index=True)) 没有连接任何东西 - 这就是我们看到 2 倍改进的原因。尝试使用 pd.concat([df_small, df_small], axis=0, ignore_index=True) 进行计算 - 这是 append 所做的,但您的性能提升消失了。 @ssk08 非常感谢您的贡献!我相应地更新了我的答案 - 你完全正确!【参考方案4】:还有一点你必须记住,Pandas 中的 APPEND() 方法不会修改原始对象。相反,它使用组合数据创建一个新的。因为涉及到创建和数据缓冲,所以性能不好。多 APPEND 操作时最好使用 CONCAT() 函数。
【讨论】:
以上是关于Pandas DataFrame concat vs append的主要内容,如果未能解决你的问题,请参考以下文章
Pandas DataFrame concat vs append
pandas中,dataframe 进行数据合并-pd.concat()
Pandas 基础 - 用 concat 组合 dataframe
pandas使用pd.concat纵向合并多个dataframe实战:多个dataframe的纵向合并为纵向合并的多个dataframe设置标识符指定数据来源
Pandas中DataFrame数据合并连接(concatmergejoin)之concat
pandas使用pd.concat横向合并多个dataframe实战:多个dataframe的横向表拼接(行对齐)多个dataframe的横向表拼接(指定join参数交集还是并集)