解压缩并阅读Dukascopy .bi5刻度文件

ajs*_*jsp 6 python csv binary lzma pandas

我需要打开一个.bi5文件并阅读内容以简短地讲述一个长篇故事.问题:我有成千上万的.bi5文件包含我需要解压缩和处理的时间序列数据(读取,转储到pandas中).

我最终专门为lzma库安装了Python 3(我通常使用2.7),因为我使用lzmaPython 2.7 的后端程序来编译恶梦,所以我承认并使用Python 3运行,但没有成功.问题太多,无法透露,没有人读长问题!

我已经包含了其中一个.bi5文件,如果有人能够将它变成Pandas Dataframe并告诉我他们是如何做到的,那将是理想的.

ps fie只有几kb,它会在一秒内下载.首先十分感谢.

(文件) http://www.filedropper.com/13hticks

ptr*_*trj 10

下面的代码应该可以解决问题.首先,它打开一个文件并在lzma中对其进行解码,然后使用struct来解压缩二进制数据.

import lzma
import struct
import pandas as pd


def bi5_to_df(filename, fmt):
    chunk_size = struct.calcsize(fmt)
    data = []
    with lzma.open(filename) as f:
        while True:
            chunk = f.read(chunk_size)
            if chunk:
                data.append(struct.unpack(fmt, chunk))
            else:
                break
    df = pd.DataFrame(data)
    return df
Run Code Online (Sandbox Code Playgroud)

最重要的是要知道正确的格式.我google了一下,试图猜测和'>3i2f'(或>3I2f)工作得很好.(它是大端3个整数2个浮点数.你的建议:'i4f'不会产生合理的浮点数 - 无论是大端还是小端.)对于struct格式语法,请参阅文档.

df = bi5_to_df('13h_ticks.bi5', '>3i2f')
df.head()
Out[177]: 
      0       1       2     3     4
0   210  110218  110216  1.87  1.12
1   362  110219  110216  1.00  5.85
2   875  110220  110217  1.00  1.12
3  1408  110220  110218  1.50  1.00
4  1884  110221  110219  3.94  1.00
Run Code Online (Sandbox Code Playgroud)

更新

比较器的输出bi5_to_dfhttps://github.com/ninety47/dukascopy,我编译和运行test_read_bi5从那里.输出的第一行是:

time, bid, bid_vol, ask, ask_vol
2012-Dec-03 01:00:03.581000, 131.945, 1.5, 131.966, 1.5
2012-Dec-03 01:00:05.142000, 131.943, 1.5, 131.964, 1.5
2012-Dec-03 01:00:05.202000, 131.943, 1.5, 131.964, 2.25
2012-Dec-03 01:00:05.321000, 131.944, 1.5, 131.964, 1.5
2012-Dec-03 01:00:05.441000, 131.944, 1.5, 131.964, 1.5
Run Code Online (Sandbox Code Playgroud)

bi5_to_df在相同的输入文件上给出:

bi5_to_df('01h_ticks.bi5', '>3I2f').head()
Out[295]: 
      0       1       2     3    4
0  3581  131966  131945  1.50  1.5
1  5142  131964  131943  1.50  1.5
2  5202  131964  131943  2.25  1.5
3  5321  131964  131944  1.50  1.5
4  5441  131964  131944  1.50  1.5
Run Code Online (Sandbox Code Playgroud)

所以一切似乎都很好(九十四的代码重新排序列).

此外,它可能更准确地使用'>3I2f'而不是'>3i2f'(即unsigned int代替int).

  • 第一列是"自纪元以来的几毫秒".如果你运行`pd.TimedeltaIndex(df [0],'ms')`,你会看到它覆盖1小时.要获取时间戳,请执行例如`ts + pd.TimedeltaIndex(df [0],'ms')`其中`ts`是您的时间戳. (2认同)
  • @RaduS不确定你的意思.您可以简单地将两列中的数字除以100,例如`df.iloc [:,[1,2]] = df.iloc [:,[1,2]]/100`.对于这个货币对,因子为100.对于另一对货币可能不同 - 它不在输入文件中编码 - 您不知道它. (2认同)