我正在使用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提到这是大熊猫的设计选择,那么,有没有办法有效地构建这个数据帧?
答案 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)