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中数千个大表的外连接

如何操作一个巨大的 csv 文件(> 12GB)?

Pandas:如何对两个特定列之间的列进行求和(动态)?

Python / Pandas:按顺序填充 NaN - 线性插值 --> ffill --> bfill

Pandas 多索引 DataFrame 到 Numpy Ndarray

在 python 2.7 中运行 Apriori 算法