Python Pandas:将 2,000,000 个 DataFrame 行转换为二进制矩阵 (pd.get_dummies()) 而不会出现内存错误?
Posted
技术标签:
【中文标题】Python Pandas:将 2,000,000 个 DataFrame 行转换为二进制矩阵 (pd.get_dummies()) 而不会出现内存错误?【英文标题】:Python Pandas: Convert 2,000,000 DataFrame rows to Binary Matrix (pd.get_dummies()) without memory error? 【发布时间】:2016-07-29 16:56:59 【问题描述】:我正在处理一个包含2,000,000
行的大型记录文件。每行包含有关电子邮件的特征和一个二进制标签[0,1]
,分别表示非垃圾邮件或垃圾邮件。
我想将所有特征(例如email_type
)转换为二进制矩阵。
这可以使用pd.get_dummies()
来完成,它从一列特征创建一个二进制矩阵。
这非常适用于数据的一小部分子样本,比如10,000
行。但是,对于100,000+
行,我看到错误Killed:9
。
为了解决这个问题,我尝试了以下方法:
步骤:
-
使用
numpyp.array_split()
将 DataFrame 拆分为 10,000 行的块
为每个 10,000 行的 DataFrame 创建一个二进制矩阵
将这些附加到 DataFrame 列表中
将这些 DataFrame 连接在一起(我这样做是为了保留每个块将包含的列的差异)
代码:
# break into chunks
chunks = (len(df) / 10000) + 1
df_list = np.array_split(df, chunks)
super_x = []
super_y = []
# loop through chunks
for i, df_chunk in enumerate(df_list):
# preprocess_data() returns x,y (both DataFrames)
[x, y] = preprocess_data(df_chunk)
super_x.append(x)
super_y.append(y)
# vertically concatenate DataFrames
super_x_mat = pd.concat(super_x, axis=0).fillna(0)
super_y_mat = pd.concat(super_y, axis=0)
# pickle (in case of further preprocessing)
super_x_mat.to_pickle('super_x_mat.p')
super_y_mat.to_pickle('super_y_mat.p')
# return values as np.ndarray
x = super_x_mat.values
y = super_y_mat.values
return[x, y]
一些示例输出:
chunks 13
chunk 0 2016-04-08 12:46:55.473963
chunk 1 2016-04-08 12:47:05.942743
...
chunk 12 2016-04-08 12:49:16.318680
Killed: 9
在处理32
块(320,000
行)之后,第 2 步(转换为二进制矩阵)内存不足,但是当块被附加到数据帧列表时可能会出现内存不足,如下所示df_chunks.append(df)
.
第 3 步内存不足,试图连接 20
成功处理的块(200,000
行)
理想的输出是numpy.ndarray
,我可以将其提供给sklearn
逻辑回归分类器。
我还可以尝试哪些其他方法?我开始更频繁地对这种规模的数据集进行机器学习。
我寻求建议并愿意接受以下建议:
-
处理每个块,使用整个数据帧中所有可能的列并在重新组合之前保存为文件
文件数据存储建议
使用不同矩阵的完全其他方法
【问题讨论】:
您的数据似乎没有那么大,所以问题肯定出在其他地方。也许比你想象的更多?我们可以看到 df.head() 吗? 目前大约有 620 个假人,但我们希望扩大到额外的 15,000 个假人 哇!在您的帖子中您提出[0,10],所以我不明白这个问题。所以你的内存崩溃是正常的,因为 600 * 100.000 是 PC 内存空间的大小。我想你必须找到另一种方法来管理你的数据:有这么多假人的二进制矩阵效率非常低。 对不起!我猜email_type
是一个误导性的例子。 location
的列具有更多值。你有什么建议吗?
对不起。我对逻辑回归分类器一无所知....
【参考方案1】:
如果您正在执行类似 one-hot 编码的操作,或者在任何情况下都会有很多零,您是否考虑过使用 sparse matrices?这应该在预处理之后完成,例如:
[x, y] = preprocess_data(df_chunk)
x = sparse.csr_matrix(x.values)
super_x.append(x)
熊猫也有sparse type:
x=x.to_sparse()
[x, y] = preprocess_data(df_chunk)
super_x.append(x)
注意:由于您是按行切割和连接,因此 csr 比 csc 更可取。
【讨论】:
以上是关于Python Pandas:将 2,000,000 个 DataFrame 行转换为二进制矩阵 (pd.get_dummies()) 而不会出现内存错误?的主要内容,如果未能解决你的问题,请参考以下文章
Python / Pandas:按顺序填充 NaN - 线性插值 --> ffill --> bfill