pandas – 庞大的稀疏数据帧,用于scipy稀疏矩阵,无需密集变换

拥有超过100万行和30列的数据,其中一列是user_id(超过1500个不同的用户).

我希望对此列进行单热编码,并使用ML算法(xgboost,FFM,scikit)中的数据.但是由于巨大的行数和唯一的用户值矩阵将是〜1百万X 1500,所以需要以稀疏格式执行此操作(否则数据会杀死所有RAM).

对我来说,通过pandas DataFrame处理数据的便捷方式,现在它也支持稀疏格式:

df = pd.get_dummies(df, columns=['user_id', 'type'], sparse=True)

工作速度非常快,RAM容量小.但是对于使用scikit algos和xgboost,必须将数据帧转换为稀疏矩阵.

有没有办法做到这一点而不是遍历列并在一个scipy稀疏矩阵中隐藏它们?
我尝试了df.as_matrix()和df.values,但所有的第一个转换数据都是密集的,因为MemoryError 🙁

附:
与获取DMatrix for xgboost相同

更新:

所以我发布下一个解决方案(将感谢优化建议):

 def sparse_df_to_saprse_matrix (sparse_df):
    index_list = sparse_df.index.values.tolist()
    matrix_columns = []
    sparse_matrix = None

    for column in sparse_df.columns:
        sps_series = sparse_df[column]
        sps_series.index = pd.MultiIndex.from_product([index_list, [column]])
        curr_sps_column, rows, cols = sps_series.to_coo()
        if sparse_matrix != None:
            sparse_matrix = sparse.hstack([sparse_matrix, curr_sps_column])
        else:
            sparse_matrix = curr_sps_column
        matrix_columns.extend(cols)

    return sparse_matrix, index_list, matrix_columns

以下代码允许获取稀疏数据帧:

one_hot_df = pd.get_dummies(df, columns=['user_id', 'type'], sparse=True)
full_sparse_df = one_hot_df.to_sparse(fill_value=0)

我创建了稀疏矩阵1,1万行x 1150列.但在创建过程中它仍然使用大量的RAM(我的12Gb边缘约10Gb).

不知道为什么,因为产生的稀疏矩阵仅使用300 Mb(从HDD加载后).有任何想法吗?

最佳答案 您应该能够以下列方式在pandas [1]中使用实验性的.to_coo()方法:

one_hot_df = pd.get_dummies(df, columns=['user_id', 'type'], sparse=True)
one_hot_df, idx_rows, idx_cols = one_hot_df.stack().to_sparse().to_coo()

这种方法不是采用DataFrame(行/列),而是采用MultiIndex中带有行和列的Series(这就是为什么需要.stack()方法).具有MultiIndex的系列需要是SparseSeries,即使您的输入是SparseDataFrame,.stack()也会返回常规Series.因此,在调用.to_coo()之前,需要使用.to_sparse()方法.

由.stack()返回的系列,即使它不是SparseSeries只包含非空的元素,因此它不应该占用比稀疏版本更多的内存(至少在np.nan类型为np.float时使用np.nan) ).

> http://pandas.pydata.org/pandas-docs/stable/sparse.html#interaction-with-scipy-sparse

点赞