문제

어떻게 든 주식 시장 데이터를 압축하는 작업이 있습니다 ... 데이터는 매일의 주식 값이 한 줄로 제공되는 파일에 있습니다. 그래서 그것은 정말 큰 파일입니다.

예,
123.45
234.75
345.678
889.56
.....

이제 문제는 Huffman 또는 Arithmetic Coding 또는 LZ Coding과 같은 표준 알고리즘을 사용하여 데이터를 압축하는 방법 (일명 중복성 감소)입니다.

첫 번째 데이터를 취한 다음 각 연속 데이터의 차이를 고려하면 차이 값에 반복이 많이 있음을 알았습니다. 이는 먼저 이러한 차이를 취하고 빈도를 찾는 경우 및 보호 기능을 찾는 경우 궁금합니다. Huffman 코딩을 사용하면 방법이 될 것입니까 ?? ...

내가 맞아? ... 누구든지 나에게 몇 가지 제안을 할 수 있습니까?

도움이 되었습니까?

해결책

나는 당신의 문제가 단순히 주가를 빼는 것보다 더 복잡하다고 생각합니다. 또한 날짜를 저장해야합니다 (파일 이름에서 추론 할 수있는 일관된 시간 범위가없는 한).

그러나 데이터의 양은 그리 크지 않습니다. 지난 30 년 동안 매일 매일 매일 매일 데이터를 가지고 있어도 300 StockD에 대해 매일 30 년 동안 매일 매일 2 년 동안 데이터를 가지고 있어도 여전히 5TB의 홈 컴퓨터 (예 : Mac Pro)에 모든 것을 저장할 수 있습니다. .

나는 매일 Yahoo에서 IBM 주식을 쫓아 내고 "정상적으로"(조정 된 닫기 만)를 저장하고 언급 한 "차이 방법"을 사용한 다음 GZIP를 사용하여 압축하는 빠르고 더러운 스크립트를 작성했습니다. 16K 대 10K를 절약 할 수 있습니다. 문제는 내가 날짜를 저장하지 않았다는 것입니다. 그리고 어떤 날짜에 어떤 가치가 일치하는지 모르겠습니다. 물론 이것을 포함시켜야합니다.

행운을 빕니다.

import urllib as ul
import binascii as ba

# root URL
url = 'http://ichart.finance.yahoo.com/table.csv?%s'

# dictionary of options appended to URL (encoded)
opt = ul.urlencode({
    's':'IBM',       # Stock symbol or ticker; IBM
    'a':'00',        # Month January; index starts at zero
    'b':'2',         # Day 2
    'c':'1978',      # Year 2009
    'd':'10',        # Month November; index starts at zero
    'e':'30',        # Day 30
    'f':'2009',      # Year 2009
    'g':'d',         # Get daily prices
    'ignore':'.csv', # CSV format
    })

# get the data
data = ul.urlopen(url % opt)

# get only the "Adjusted Close" (last column of every row; the 7th)

close = []

for entry in data:
    close.append(entry.strip().split(',')[6])

# get rid of the first element (it is only the string 'Adj Close') 
close.pop(0)

# write to file
f1 = open('raw.dat','w')
for element in close:
    f1.write(element+'\n')
f1.close()

# simple function to convert string to scaled number
def scale(x):
    return int(float(x)*100)

# apply the previously defined function to the list
close = map(scale,close)

# it is important to store the first element (it is the base scale)
base = close[0]

# normalize all data (difference from nom)
close = [ close[k+1] - close[k] for k in range(len(close)-1)]

# introduce the base to the data
close.insert(0,base)



# define a simple function to convert the list to a single string
def l2str(list):
    out = ''
    for item in list:
        if item>=0:
            out += '+'+str(item)
        else:
            out += str(item)
    return out

# convert the list to a string
close = l2str(close)

f2 = open('comp.dat','w')
f2.write(close)
f2.close()

이제 "원시 데이터"(RAW.DAT)와 "압축 형식"을 제안하는 (comp.dat)를 비교하십시오.

:sandbox jarrieta$ ls -lh
total 152
-rw-r--r--  1 jarrieta  staff    23K Nov 30 09:28 comp.dat
-rw-r--r--  1 jarrieta  staff    47K Nov 30 09:28 raw.dat
-rw-r--r--  1 jarrieta  staff   1.7K Nov 30 09:13 stock.py
:sandbox jarrieta$ gzip --best *.dat
:sandbox jarrieta$ ls -lh
total 64
-rw-r--r--  1 jarrieta  staff    10K Nov 30 09:28 comp.dat.gz
-rw-r--r--  1 jarrieta  staff    16K Nov 30 09:28 raw.dat.gz
-rw-r--r--  1 jarrieta  staff   1.7K Nov 30 09:13 stock.py

다른 팁

요즘 많은 압축 도구는 이러한 기술의 조합을 사용하여 다양한 데이터에 우수한 비율을 제공합니다. 상당히 일반적이고 현대적인 것으로 시작할 가치가있을 수 있습니다. bzip2 Huffman Coding을 사용하여 다양한 종류의 중복성을 가져 오기 위해 데이터를 뒤섞는 다양한 트릭과 결합합니다 (페이지에는 다양한 구현에 대한 링크가 포함되어 있음).

실행 길이 인코딩이 적합 할 수 있습니까? 확인 해봐 여기. 작동 방식에 대한 극단적 인 간단한 예를 제공하려면 ASCII 코드의 데이터 라인이 있습니다 ... 30 바이트 길이

HHHHHHHHEEEEEEELLLLLLLLOOOOOO

RLE를 적용하면 8 바이트로 얻을 수 있습니다.

9H7E8L6O
  • 9 H
  • 일곱 E
  • 여덟 l
  • Six O

결과적으로 약 27% 감소 (예제 라인의 압축 비율은 8/30)

어떻게 생각해?

이것이 도움이되기를 바랍니다.

연속 데이터의 차이를 조정 한 다음 실행 길이 인코딩을 사용하십시오. (rle).

또한 데이터를 정수로 변환 한 다음 차이를 강화해야합니다.

가장 좋은 것은 적응 형 차동 압축입니다 (올바른 이름을 잊어 버립니다). 당신이 매일 차이를 취할뿐만 아니라 예측 변수를 계산하고 실제로 그 차이를 수행 할 수 있습니다. 일반적으로 일반 선형 예측 변수를 능가합니다.

당신이 할 수있는 일을 좋아한다면, 교차 적응성은 전반적으로 주식 시장이 압축에 대한 더 나은 예측 변수를 선택하는 데 사용되는 자체 트렌드입니다.

기본 파일을 세그먼트 블록 형식으로 분류 한 다음 개별 세그먼트를 개별적으로 압축하는 것이 좋습니다. 이로 인해 최적 최적화 압축이 발생해야합니다. 감압 측면에서는 이러한 개별 세그먼트를 개별적으로 압축하고 원래 텍스트 파일을 재구성해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top