拥有超过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 :(
P.S。 与获取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加载后)。有什么想法吗?
答案 0 :(得分:1)
您应该能够以下列方式在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
(行/列),而是在Series
中使用MultiIndex
行和列(这就是为什么需要.stack()
} 方法)。这个Series
MultiIndex
需要SparseSeries
,即使您的输入为SparseDataFrame
,.stack()
也会返回常规Series
。因此,您需要在调用.to_sparse()
之前使用.to_coo()
方法。
Series
返回的.stack()
,即使它不是SparseSeries
,也只包含非空元素,因此它不应占用比稀疏版本更多的内存(在当类型为np.nan
时,至少使用np.float
。
答案 1 :(得分:0)
几个月前我的答案有帮助吗?
Pandas sparse dataFrame to sparse matrix, without generating a dense matrix in memory
它已被接受,但我没有得到任何进一步的反馈。
我熟悉scipy
sparse
格式及其输入,但对pandas
稀疏知之甚少。