2016-12-16 28 views
5

.bi5 파일을 열고 내용을 읽어서 짧은 이야기를 짧게 줄여야합니다. 문제 : 나는 수천 개의 .bi5 파일에 압축을 풀고 처리해야하는 (시계열을 읽고 판다로 덤프) 시계열 데이터를 포함하고 있습니다. 내가 파이썬 2.7의 lzma 백 포트를 사용하는 악몽을 컴파일로 실행으로Dukascopy .bi5 진드기 파일의 압축을 풀고 읽으십시오.

나는, 특히 lzma 라이브러리에 대한 파이썬 3 (I 일반적으로 2.7를 사용) 설치, 종료, 그래서 나는 인정하지 않고 파이썬 3으로 실행되지만으로 성공. 문제는 누설하기에는 너무 많습니다. 아무도 긴 질문을 읽지 않습니다!

.bi5 파일 중 하나를 포함 시켰습니다. 누군가가 팬더 데이터 프레임에 파일을 가져 와서 어떻게했는지를 보여 주면 이상적입니다.

ps ps는 단 몇 kb이며, 초 단위로 다운로드됩니다. 미리 감사드립니다.

(파일) http://www.filedropper.com/13hticks

+0

원래 데이터의 형식을 알고 계십니까? 예를 들면 : (int, int, int, float, float) 각 줄에 있습니까? – ptrj

+0

32 비트 정수 : 에포크 이후의 밀리 초, 32 비트 float : Ask price, 32 비트 float : 입찰 가격, 32 비트 float : 32 비트 float : 32 비트 float : 입찰량. 이 작업을 위해 특별히 C++ 라이브러리가 있지만 파이썬에서 작업해야합니다. https : // github에서 확인할 수 있습니다.com/ninety47/dukascopy – ajsp

+0

파이썬 2.7입니다. – ajsp

답변

7

아래의 코드는 트릭을 할해야합니다. 먼저 파일을 열고 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 

가장 중요한 것은 올바른 형식을 알아야한다는 것입니다. 나는 주위를 봤 거든 추측하려고하고 '>3i2f' (또는 >3I2f) 꽤 잘 작동합니다. (big endian 3 ints 2 floats입니다.) 당신이 제안하는 것 : 'i4f'은 크고 작은 엔디안에 관계없이 의미있는 수레를 생성하지 않습니다. struct 및 형식 구문은 docs을 참조하십시오.

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 

업데이트 내가 컴파일 https://github.com/ninety47/dukascopy, 와 bi5_to_df의 출력을 비교하고 거기에서 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 

그리고 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 

그래서 모든 (ninety47의 코드 열을 재정렬) 괜찮을 것 같다.

또한, '>3I2f' 대신 '>3i2f'을 사용하는 것이 아마 더 정확 (즉, 대신 intunsigned int).

+0

그럴듯한 ptrj 보인다. 첫 번째 열은 타임 스탬프라고 가정합니다. 그러나 정확하고 데이터의 실제 표현 인 경우 날짜가 지정된 폴더 구조에서 초기 타임 스탬프를 가져와 추가해야합니다 (긴 이야기). 나는 내일 그것을 단지 점검 할 것이다. 그러나 당신이 현상금을 저축했던 것처럼 그것은 보인다. 곧 이야기. – ajsp

+1

첫 번째 열은 "신기원 이후의 밀리 초"입니다. 'pd.TimedeltaIndex (df [0], 'ms')'를 실행하면, 1 시간을 커버하는 것을 볼 수 있습니다. 타임 스탬프를 얻으려면, 예를 들어'ts + pd.TimedeltaIndex (df [0], 'ms')'여기서'ts'는 타임 스탬프입니다. – ptrj

+0

처음 두 개의 열이 떠 다니는 것으로 생각됩니다. 그것은 통화의 가격입니다 (EURUSD). 아마도 공간을 절약하기 위해이 방법으로 압축되었을 가능성이 있습니까? – ajsp

0

numpy를 사용하여 데이터를 구문 분석 한 후 팬더로 전송 해 보았습니까? 어쩌면 먼 길을 찾는 것이지만, 팬더에서 분석을하기 전에 데이터를 조작하고 정리할 수 있습니다. 또한 그들 사이의 통합도 매우 간단합니다.