我什么时候应该使用熊猫'分类dtype?

时间:2018-01-15 02:58:53

标签: python pandas memory categorical-data

我的问题是关于优化pandas系列的内存使用情况。文档note

  

Categorical的内存使用量与类别数量加上数据长度成正比。相反,object dtype是数据长度的常数。

我的理解是,pandas Categorical数据实际上是映射到表示类别的唯一(向下转换)整数,其中整数本身占用(可能)比生成的字符串更少的字节向上object dtype。

我的问题:是否有任何经验法则,以便在使用pd.Categoricalobject上保存内存?上述比例是多么直接,并且它也不取决于系列中每个元素(字符串)的长度?

在下面的测试中,pd.Categorical似乎很快就获胜了。

import string

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

np.random.seed(444)
%matplotlib inline

def mem_usage(obj, index=False, total=True, deep=True):
    """Memory usage of pandas Series or DataFrame."""
    # Ported from https://www.dataquest.io/blog/pandas-big-data/
    usg = obj.memory_usage(index=index, deep=deep)
    if isinstance(obj, pd.DataFrame) and total:
        usg = usg.sum()
    # Bytes to megabytes
    return usg / 1024 ** 2

catgrs = tuple(string.printable)

lengths = np.arange(1, 10001, dtype=np.uint16)
sizes = []
for length in lengths:
    obj = pd.Series(np.random.choice(catgrs, size=length))
    cat = obj.astype('category')
    sizes.append((mem_usage(obj), mem_usage(cat)))
sizes = np.array(sizes)

fig, ax = plt.subplots()
ax.plot(sizes)
ax.set_ylabel('Size (MB)')
ax.set_xlabel('Series length')
ax.legend(['object dtype', 'category dtype'])
ax.set_title('Memory usage of object vs. category dtype')

enter image description here

虽然,对于n <125,pd.Categorical 稍微更大。

fig, ax = plt.subplots()
ax.plot(sizes[:200])
ax.set_ylabel('Size (MB)')
ax.set_xlabel('Series length')
ax.legend(['object dtype', 'category dtype'])
ax.set_title('Memory usage of object vs. category dtype')

enter image description here

1 个答案:

答案 0 :(得分:0)

categorical astype 使用较少的内存。然而,一种热编码允许您保持级别的分类排名。您可以分析分类器系数以了解分类数据的行为和预测。