我正在从通过 Sierra Chart 从 Interactive Brokers 5 秒 OHLCVT 柱接收数据的文件中获取数据。
按照之前帖子中的建议,我没有将每个新行附加到数据框中,而是使用历史文件构建了一个数据框,并将 5000 条带有正确时间戳的“空白”记录附加到其中。然后我将每个新行写在一个空白行上,如果缺少时间戳并更新指针,则填充任何行。
这很好用。这是当前的类和函数。我的初始版本创建了 5000 行 NaN (OHLCVxyz)。我认为从最终数据类型开始会更整洁,因此将“空白”记录转换为零,OHLC 为浮点数,Vxyz 为整数,使用:
dg.iloc[0:5000] = 0.0
dg[[v, x, y, z]] = dg[[v, x, y, z]].astype('int')
每增加 5000 行只会发生一次(恒指每天一次)。令我惊讶的是对读/写循环的影响。它们从每行 0.8 毫秒变为 3.4 毫秒。唯一的变化是从 NaN 到零。
这张图片显示了一个带有零填充帧的初始运行(参见 timestats 0.0038),然后是一个带有 NaN 填充帧的运行(timestats 0.0008)。
谁能提供有关为什么写入 [0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0] 而不是 [NaN, NaN, NaN, NaN, NaN, NaN, NaN 的字段可能会增加这么多时间的见解, 南] ?
也欢迎任何关于代码改进的想法。:)
谢谢
编辑+17 小时
根据@BrenBarn 的问题,我构建了一个更简单的模型,任何人都可以在没有数据的情况下运行。在这样做的过程中,我消除了 NaN 是否会影响它的问题。在这个版本中,我能够将 0.0s 写入两个版本,并且区别是相同的:
- 具有 8 列浮点数的数组的添加速度比具有 4 列浮点数和 4 个 int64 的数组快 10 倍。
- 在每种情况下,添加的行都是 [1.0, 2.0, 3.0, 4.0, 5, 6, 7, 8]
- 使用 self.df.iloc[self.end] = datarow 和增量结束添加 10000 次。
因此,除非我弄错了(总是可能的),否则添加到具有 4 列浮点数和 4 个整数的数据帧似乎需要 10 倍的时间。这是熊猫的问题还是人们应该期待的问题?
我认为在添加之前拥有 350,000 行 8 列的数组会产生显着差异。我最初添加到 10 行的测试显示没有影响 - 我必须回去重新测试它们。
编辑+10 分钟
不,我返回并创建了只有 10 行的初始数组,并且对添加循环的影响没有改变,因此它不是原始数组/数据帧的大小。很可能在我之前的测试中我认为我已经将列转换为整数,但我没有 - 检查这证明我认为会执行此操作的命令没有。
da = SierraFrame(range(10), np.zeros((10,8)))
da.extend_frame1()
编辑和可能的答案+35 分钟
这个问题不应该更详细地回答。
在这一点上,我的假设是,如果 df 包含所有一种类型,而不是包含浮点数和整数列。我刚刚使用所有 int64 对其进行了测试,所有浮点数的平均添加时间为 0.41 毫秒,而混合数据帧的平均添加时间为 2.8 毫秒。Int8s 耗时 0.39 毫秒。我猜这种混合会影响 pandas 优化其动作的能力,所以如果效率非常重要,那么所有列都是相同类型(可能是 float64)的数据框是最好的选择。
使用 Python 3.3.1 在 Linux x64 上进行的测试