【问题标题】:Data Compression数据压缩
【发布时间】:2009-11-30 01:38:57
【问题描述】:

我有一个任务以某种方式压缩股票市场数据...数据在一个文件中,其中每天的股票价值在一行中给出,依此类推...所以这是一个非常大的文件。

例如,
123.45
234.75
345.678
889.56
.....

现在的问题是如何使用 Huffman 或算术编码或 LZ 编码等标准算法压缩数据(也就是减少冗余)...哪种编码最适合此类数据??...

我注意到,如果我获取第一个数据,然后考虑每个连续数据之间的差异,差异值会有很多重复......这让我想知道是否首先获取这些差异,找到它们的频率,因此概率然后使用霍夫曼编码将是一种方式??...

我说的对吗?...谁能给我一些建议。

【问题讨论】:

标签: compression huffman-code entropy data-compression


【解决方案1】:

我认为你的问题比仅仅减去股票价格更复杂。您还需要存储日期(除非您有可以从文件名推断出的一致时间跨度)。

不过,数据量并不是很大。即使您在过去 30 年中的每一天、每一年的每一秒都有数据,有 300 个库存,您仍然可以设法将所有这些数据存储在更高端的家用计算机(例如,MAC Pro)中,因为这相当于 5Tb 未压缩.

我写了一个快速而肮脏的脚本,它将每天在 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

【讨论】:

  • 请注意,我对股票字典的评论显示起始日期为“2009”,而实际上它是 1978 年......所以我正在为 IBM 追逐 30 年的每日股票数据。
  • 嘿,非常感谢,这真的很有帮助......好吧,现在日期实际上并不重要......我的主要重点是尽可能压缩股票指数数据......并且我必须自己开发(编码)压缩代码,不能使用预构建的软件......我只会使用一种算法......所以我的问题将是获得霍夫曼编码的这个“差异”值的概率分布说时不时地对其进行解码(解压缩)。
【解决方案2】:

如今,许多压缩工具结合使用这些技术来为各种数据提供良好的比率。可能值得从一些相当普遍和现代的东西开始,比如bzip2,它使用霍夫曼编码结合各种技巧,将数据打乱以产生各种冗余(页面包含指向更下方各种实现的链接)。

【讨论】:

    【解决方案3】:

    游程编码可能合适吗?看看here。举一个非常简单的例子来说明它是如何工作的,下面是一行 ascii 代码中的数据...30 字节长

    HHHHHHHEEEEEEELLLLLLLOOOOOOO

    对它应用 RLE,你会得到 8 个字节:

    9H7E8L6O
    • 九个H
    • 七个E
    • 八个L
    • 六个O

    因此减少了大约 27%(示例行的压缩比为 8/30)

    你怎么看?

    希望这会有所帮助, 最好的祝福, 汤姆。

    【讨论】:

      【解决方案4】:

      计算连续数据的差异,然后使用Run Length Encoding (RLE)

      你还需要将数据转换为整数,然后计算差异。

      【讨论】:

        【解决方案5】:

        最好的方法是自适应差分压缩(我忘记了正确的名称)。您不仅可以每天计算差异,还可以计算预测变量并实际进行差异计算。通常优于正常的线性预测变量。

        如果你想变得花哨,你可以做的是交叉自适应,其中股票市场整体有它自己的趋势,可以用来选择更好的压缩预测指标。

        【讨论】:

          【解决方案6】:

          我建议您将主文件分解为分段的块格式,然后分别压缩各个分段;这应该会导致最大程度的优化压缩。 在解压方面,您必须分别解压这些单独的片段,然后重建原始文本文件。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-03-16
            • 2020-06-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多