如何在构造DataFrame时填充缺失的值?

时间:2014-12-19 03:46:03

标签: python pandas

我正在使用pandas来存储一个很大但很稀疏的矩阵(50,000行* 100,000列),这个矩阵的每个元素都是一个从0.00到1.00的浮点数。原始元素值存储在python dict中(仅存储已知值的元素)。

现在的问题是如何从dict中有效地构造一个pandas.DataFrame。

如果我使用float64,那么这个矩阵的物理尺寸的粗略估计将是:(50,000 * 100,000 * 8)= 37GB ,这远远大于我的机器的内存大小

但是,我注意到,因为每个元素的范围是从0.00到1.00并且我只关心前两个数字,所以我可以通过乘以100将每个元素转换为无符号的8位整数然后转换为np .uint8,可以将此数据帧缩小到可接受的大小:(1/8 * 37GB)

我试过这个方法,但是pandas.DataFrame并没有像我期望的那样工作。当我在pd.DataFrame()构造函数中指定dtype时,最终结果仍然是float64。

以下是一个示例代码:

In [87]: dc = {'A':{'a':np.uint8(1.2), 'c':np.uint8(3.2)}, 'B':{'a':np.uint8(1.2), \
               'b':np.uint8(2.2)}, 'C':{'b':np.uint8(2.2), 'd':np.uint8(4.2)}}

In [88]: dc
Out[88]: {'A': {'a': 1, 'c': 3}, 'B': {'a': 1, 'b': 2}, 'C': {'b': 2, 'd': 4}}

In [89]: type(dc['A']['a'])
Out[89]: numpy.uint8

In [90]: df = pd.DataFrame(dc, index=['a', 'b', 'c','d'], dtype=np.uint8)

In [91]: df
Out[91]: 
    A   B   C
a   1   1 NaN
b NaN   2   2
c   3 NaN NaN
d NaN NaN   4

In [92]: df.dtypes
Out[92]: 
A    float64
B    float64
C    float64
dtype: object

@ zero323提到这是大熊猫的设计选择,那么,有没有办法有效地构建这个数据帧?

1 个答案:

答案 0 :(得分:2)

它不会帮助你,但它是一种预期的行为。引用Caveats and Gotchas

  

当通过reindex或其他方式将NAs引入现有的Series或DataFrame时,布尔和整数类型将被提升为不同的dtype以存储NA。

@EdChum的评论提供了最佳解决方案,但如果真的必须使用dicts,那么你可以尝试这样的事情:

# Choose some default value
default = 0
# Prepare dict with defaults
defaults = {k: default for k in chain(*(x.keys() for x in dc.values()))}

# Fill gaps if needed and construct data frame
df = pd.DataFrame(
    {k: dict(defaults.items() + v.items()) for k, v in dc.items()},
    index=['a', 'b', 'c','d'], dtype=np.uint8)