---
layout: post
title: "如何壓縮 Numpy 資料"
modified:
categories: [Python]
description:
tags: [Numpy, Python, compress, memory]
image:
  feature:
  credit:
  creditlink:
---

這次遇上的問題是在計算過程儲存了太多的 Numpy 陣列，結果居然吃到了 swap 讓系統接近當掉。
趕快搜尋有沒有什麼辦法可以減少記憶體佔用。

### 可能的作法
* 把資料先用 pickle dump 儲存到硬碟，等需要實在拿回來用。
* 相對的缺點是會有 IO 的速度耗損

***

* 壓縮 Numpy array 記在記憶體中，等需要時在解壓縮。
* 缺點是在壓縮和解壓縮時會有計算的耗損。

***

這次針對壓縮解壓縮來嘗試，搜尋到的原始教學是從 Stack Overflow[^1] 找到的。

[^1]: <http://stackoverflow.com/questions/39035983/compress-zip-numpy-arrays-in-memory>

### 壓縮方法

Numpy 本身提供一個方法 `numpy.savez_compressed`[^2] 可以把 numpy.array 以壓縮的格式
儲存在 `file` 或 `file like object` 中。如果沒有指定名稱就依序命名為 'arr_0', 'arr_1', 'arr_2'...

在原本的 Stack Overflow 中使用的是 `io.BytesIO` 來儲存。
不過後來嘗試使用 `cStringIO.StringIO()` 發現它佔用的記憶體用量更少，或許自製 File like object 會更少吧？

[^2]: <https://docs.scipy.org/doc/numpy/reference/generated/numpy.savez_compressed.html#numpy.savez_compressed>

{% highlight python %}
a = io.BytesIO()
b = cStringIO.StringIO()

print (sys.getsizeof(a), sys.getsizeof(b))
# (96, 56)

def compress(nparray, b):
    np.savez_compressed(b, nparray)
{% endhighlight %}

Add compress Np array method
Add compress Np array method
