Python Pandas:如何将200万行DataFrame转换为二进制矩阵(pd.get_dummies()),避免内存错误?

9
我正在处理一个包含2000000行记录的大型文件。每行都包含有关电子邮件的特征和二进制标签[0,1],分别表示非垃圾邮件或垃圾邮件。
我想将所有特征(例如取值为[1,10]的email_type)转换为二进制矩阵。
这可以使用pd.get_dummies()来完成,该函数可以从特征列创建一个二进制矩阵。
在小数据子样本上,比如10000行,它可以完美地工作。但是,在超过100000行的情况下,我会看到错误Killed:9。
为了解决这个问题,我尝试了以下方法:
步骤:
1.使用numpyp.array_split()将DataFrame拆分成10,000行的块。 2.为每个10,000行的DataFrame创建一个二进制矩阵。 3.将它们附加到一个DataFrame列表中。 4.连接这些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行)后出现内存不足的问题,造成内存不足的原因是该块被附加到数据帧列表中,代码如下:df_chunks.append(df)。
第三步在尝试连接20个已成功处理的块(200,000行)时出现内存不足的问题。
理想的输出是numpy.ndarray,可以将其提供给sklearn逻辑回归分类器。
我还能尝试哪些方法?我经常开始使用这么大的数据集进行机器学习。
我需要建议并可以接受以下建议:
1.处理每个块,使用整个数据帧中的所有可能列,并在重新组合之前保存为文件
2.文件数据存储的建议
3.完全使用不同矩阵的其他方法

你的数据似乎不是很大,所以问题一定出在其他地方。也许有比你想象中更多的虚拟变量?我们可以看一下 df.head() 吗? - B. M.
目前大约有620个虚拟对象,但我们希望扩展到另外15,000个虚拟对象。 - jfive
哇!在你的帖子中,你提到了[0,10],所以我不明白问题出在哪里。因此,你的内存崩溃是正常的,因为600 * 100.000是PC内存空间的数量级。我猜你需要找到另一种方法来管理你的数据:拥有这么多虚拟值的二进制矩阵效率非常低下。 - B. M.
抱歉!我想email_type是一个误导性的例子。location列有更多的值。你有什么建议吗? - jfive
抱歉,我对逻辑回归分类器一无所知... - B. M.
显示剩余3条评论
1个回答

6
如果你正在进行像one-hot编码这样的操作,或者在任何情况下都会有大量的零值,请考虑使用稀疏矩阵。这应该在预处理之后进行,例如: scipy.sparse.csr_matrix
[x, y] = preprocess_data(df_chunk)
x = sparse.csr_matrix(x.values)
super_x.append(x)

pandas还具有稀疏类型

x=x.to_sparse()
[x, y] = preprocess_data(df_chunk)
super_x.append(x)

请注意:由于您正在按行剪切和连接,因此csr比csc更可取。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接