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