-
08-07-2019 - |
문제
어떻게 든 주식 시장 데이터를 압축하는 작업이 있습니다 ... 데이터는 매일의 주식 값이 한 줄로 제공되는 파일에 있습니다. 그래서 그것은 정말 큰 파일입니다.
예,
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).
또한 데이터를 정수로 변환 한 다음 차이를 강화해야합니다.
가장 좋은 것은 적응 형 차동 압축입니다 (올바른 이름을 잊어 버립니다). 당신이 매일 차이를 취할뿐만 아니라 예측 변수를 계산하고 실제로 그 차이를 수행 할 수 있습니다. 일반적으로 일반 선형 예측 변수를 능가합니다.
당신이 할 수있는 일을 좋아한다면, 교차 적응성은 전반적으로 주식 시장이 압축에 대한 더 나은 예측 변수를 선택하는 데 사용되는 자체 트렌드입니다.
기본 파일을 세그먼트 블록 형식으로 분류 한 다음 개별 세그먼트를 개별적으로 압축하는 것이 좋습니다. 이로 인해 최적 최적화 압축이 발생해야합니다. 감압 측면에서는 이러한 개별 세그먼트를 개별적으로 압축하고 원래 텍스트 파일을 재구성해야합니다.