了解 Pandas 中的稀疏数据结构
Understanding Sparse Data Structures in Pandas
我必须处理比本地计算机上的 RAM 大的数据帧。因此,我正在考虑使用稀疏数据结构。
需求最初是在创建虚拟变量时出现的,从手册中,我注意到 pd.get_dummies() 有一个 sparse = True
选项,所以我在测试样本上使用了它并得到了预期的行为:
>>> test=pd.get_dummies(df, sparse=True)
>>> testSparsed = test.to_sparse()
>>> testDensed = test.to_dense()
>>> test.memory_usage().sum()
# expect no change as already sparse
>>> testSparsed.memory_usage().sum()
# expect change on conversion to dense
>>> testDensed.memory_usage().sum()
89652
89652
25789582
但是,作为实验,我尝试在创建虚拟对象后将 'normal' df 转换为稀疏 df,这是我遇到意外行为的地方:
>>> test2=pd.get_dummies(df, sparse=False)
>>> test2Sparsed = test2.to_sparse()
>>> test2Densed = test2.to_dense()
>>> test2.memory_usage().sum()
# expect change on sparse conversion
>>> test2Sparsed.memory_usage().sum()
# expect same as test2
>>> test2Densed.memory_usage().sum()
25789582
25789582
25789582
我希望 test2Sparsed.memory_usage().sum()
应该小于其他值,但事实并非如此。
我在 Stack Overflow 上搜索过,但没有找到任何相关答案。
当对这些对象进行酸洗并在命令行上查看文件大小时,我得到以下信息
> ls -sh test testSparsed testDensed test2 test2Sparsed test2Densed
2992 test 2992 testSparsed 50856 testDensed 50864 test2
53344 test2Sparsed 50864 test2Densed
检查 test2 数据帧的类型表明 test2Sparsed 的内存应该更小:
>>> type(test2)
>>> type(test2Sparsed)
>>> type(test2Densed)
pandas.core.frame.DataFrame
pandas.core.sparse.frame.SparseDataFrame
pandas.core.frame.DataFrame
所以我的问题是,为什么在密集数据帧上调用 .to_sparse()
似乎没有改变它的大小?
正如我在 pandas.DataFrame 文档中看到的那样。您必须使用 fill_value
指定要在表示中省略的值。默认 fill_value = None
.
DataFrame.to_sparse(fill_value=None, kind='block')
当您使用 test = pd.get_dummies(df, sparse=True)
时,DataFrame test
的值等于 SparseArray。您可以看到 fill_value
的默认值取决于数据类型。
data.dtype na_value
float np.nan
int 0
bool False
datetime64 pd.NaT
timedelta64 pd.NaT
我必须处理比本地计算机上的 RAM 大的数据帧。因此,我正在考虑使用稀疏数据结构。
需求最初是在创建虚拟变量时出现的,从手册中,我注意到 pd.get_dummies() 有一个 sparse = True
选项,所以我在测试样本上使用了它并得到了预期的行为:
>>> test=pd.get_dummies(df, sparse=True)
>>> testSparsed = test.to_sparse()
>>> testDensed = test.to_dense()
>>> test.memory_usage().sum()
# expect no change as already sparse
>>> testSparsed.memory_usage().sum()
# expect change on conversion to dense
>>> testDensed.memory_usage().sum()
89652
89652
25789582
但是,作为实验,我尝试在创建虚拟对象后将 'normal' df 转换为稀疏 df,这是我遇到意外行为的地方:
>>> test2=pd.get_dummies(df, sparse=False)
>>> test2Sparsed = test2.to_sparse()
>>> test2Densed = test2.to_dense()
>>> test2.memory_usage().sum()
# expect change on sparse conversion
>>> test2Sparsed.memory_usage().sum()
# expect same as test2
>>> test2Densed.memory_usage().sum()
25789582
25789582
25789582
我希望 test2Sparsed.memory_usage().sum()
应该小于其他值,但事实并非如此。
我在 Stack Overflow 上搜索过,但没有找到任何相关答案。
当对这些对象进行酸洗并在命令行上查看文件大小时,我得到以下信息
> ls -sh test testSparsed testDensed test2 test2Sparsed test2Densed
2992 test 2992 testSparsed 50856 testDensed 50864 test2
53344 test2Sparsed 50864 test2Densed
检查 test2 数据帧的类型表明 test2Sparsed 的内存应该更小:
>>> type(test2)
>>> type(test2Sparsed)
>>> type(test2Densed)
pandas.core.frame.DataFrame
pandas.core.sparse.frame.SparseDataFrame
pandas.core.frame.DataFrame
所以我的问题是,为什么在密集数据帧上调用 .to_sparse()
似乎没有改变它的大小?
正如我在 pandas.DataFrame 文档中看到的那样。您必须使用 fill_value
指定要在表示中省略的值。默认 fill_value = None
.
DataFrame.to_sparse(fill_value=None, kind='block')
当您使用 test = pd.get_dummies(df, sparse=True)
时,DataFrame test
的值等于 SparseArray。您可以看到 fill_value
的默认值取决于数据类型。
data.dtype na_value
float np.nan
int 0
bool False
datetime64 pd.NaT
timedelta64 pd.NaT