当 Sparse = True 时 pd.get_dummies 数据帧大小与 Sparse = False 时相同

Posted

技术标签:

【中文标题】当 Sparse = True 时 pd.get_dummies 数据帧大小与 Sparse = False 时相同【英文标题】:pd.get_dummies dataframe same size when Sparse = True as when Sparse = False 【发布时间】:2019-01-13 12:23:51 【问题描述】:

我有一个包含多个字符串列的数据框,我想将其转换为分类数据,以便我可以运行一些模型并从中提取重要特征。

但是,由于唯一值的数量,one-hot 编码数据会扩展为大量列,这会导致性能问题。

为了解决这个问题,我正在尝试使用 get_dummies 中的 Sparse = True 参数。

test1 = pd.get_dummies(X.loc[:,['col1','col2','col3','col4']].head(10000))
test2 = pd.get_dummies(X.loc[:,['col1','col2','col3','col4']].head(10000),sparse = True)

但是,当我检查两个比较对象的信息时,它们占用的内存量相同。 Sparse = True 似乎没有使用更少的空间。这是为什么呢?

test1.info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 10000 entries, 537293 to 752152
Columns: 2253 entries,...
dtypes: uint8(2253)
memory usage: 21.6 MB

test2.info()
<class 'pandas.core.sparse.frame.SparseDataFrame'>
Int64Index: 10000 entries, 537293 to 752152
Columns: 2253 entries, ...
dtypes: uint8(2253)
memory usage: 21.9 MB

【问题讨论】:

【参考方案1】:

我查看了 pandas get_dummies 源代码,但到目前为止还没有发现错误。这是我在下面做的一个小实验(前半部分是用真实数据重现你的问题)。

In [1]: import numpy as np
   ...: import pandas as pd
   ...: 
   ...: a = ['a', 'b'] * 100000
   ...: A = ['A', 'B'] * 100000
   ...: 
   ...: df1 = pd.DataFrame('a': a, 'A': A)
   ...: df1 = pd.get_dummies(df1)
   ...: df1.info()
   ...:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 200000 entries, 0 to 199999
Data columns (total 4 columns):
A_A    200000 non-null uint8
A_B    200000 non-null uint8
a_a    200000 non-null uint8
a_b    200000 non-null uint8
dtypes: uint8(4)
memory usage: 781.3 KB

In [2]: df2 = pd.DataFrame('a': a, 'A': A)
   ...: df2 = pd.get_dummies(df2, sparse=True)
   ...: df2.info()
   ...:
<class 'pandas.core.sparse.frame.SparseDataFrame'>
RangeIndex: 200000 entries, 0 to 199999
Data columns (total 4 columns):
A_A    200000 non-null uint8
A_B    200000 non-null uint8
a_a    200000 non-null uint8
a_b    200000 non-null uint8
dtypes: uint8(4)
memory usage: 781.3 KB

到目前为止,结果与您的结果相同(df1 的大小等于 df2 的大小),但如果我使用 to_sparsefill_value=0df2 显式转换为 sparse

In [3]: df2 = df2.to_sparse(fill_value=0)
   ...: df2.info()
   ...:
<class 'pandas.core.sparse.frame.SparseDataFrame'>
RangeIndex: 200000 entries, 0 to 199999
Data columns (total 4 columns):
A_A    200000 non-null uint8
A_B    200000 non-null uint8
a_a    200000 non-null uint8
a_b    200000 non-null uint8
dtypes: uint8(4)
memory usage: 390.7 KB

现在内存使用量减少了一半,因为一半的数据是0

总之,我不确定为什么 get_dummies(sparse=True) 不会压缩数据帧,即使它被转换为 SparseDataFrame,但有一个解决方法。相关讨论在 github get_dummies with sparse doesn't convert numeric to sparse 进行,但结论似乎仍悬而未决。

【讨论】:

以上是关于当 Sparse = True 时 pd.get_dummies 数据帧大小与 Sparse = False 时相同的主要内容,如果未能解决你的问题,请参考以下文章

mongoDb/Mongoose:使 emailId 唯一字段[重复]

sparse_softmax_cross_entropy_with_logits

如何使用 sparse_softmax_cross_entropy_with_logits 在张量流中实现加权交叉熵损失

ValueError: Only call `sparse_softmax_cross_entropy_with_logits` with named a

ImportError: No module named scipy.sparse

ImportError: No module named scipy.sparse