我正在尝试将具有分类特征的数据框直接枢轴到稀疏矩阵中。我的问题类似于这个问题,或者这个问题,但是我的数据框架包含多个分类变量,所以这些方法不起作用。
此代码目前工作,但df.pivot()
与密集矩阵和我的真实数据集一起工作,我耗尽了RAM。你能建议一种从一开始就使用稀疏矩阵的方法吗?
import pandas as pd
from scipy.sparse import csr_matrix
from sklearn.preprocessing import OneHotEncoder
# Example dataframe
data = {
'id':[13,13,14,14,14,15],
'name':['alex', 'mary', 'alex', 'barry', 'john', 'john'],
'categ': ['dog', 'cat', 'dog', 'ant', 'fox', 'seal'],
'size': ['big', 'small', 'big', 'tiny', 'medium', 'big']
}
df = pd.DataFrame(data)
# Pivoting -- problematic step creating a huge dense matrix
pivot = df.pivot(index='id', columns='name', values=['categ','size']).fillna('-')
cols = pivot.columns.to_flat_index().str.join('_')
pivot.columns = cols
# One hot encoding into a sparse matrix
encoder = OneHotEncoder(sparse_output=True)
pivot_enc = encoder.fit_transform(pivot)
pivot = pd.DataFrame.sparse.from_spmatrix(
pivot_enc, columns=encoder.get_feature_names_out())
print(pivot.dtypes)
谢谢你的帮助!
技巧在于使用groupby(),它可以直接与Sparse
类型一起工作,但仅当分类变量首先使用.cat.codes
进行编码时。
这里是使用稀疏矩阵的答案:
for col in ['categ', 'size']:
df[col] = df[col].astype('category').cat.codes
# Group by into sparse columns
piv = df.groupby(['id', 'name'])[['categ', 'size']].first().astype('Sparse')
# Unstack keeps sparse format
piv = piv.unstack(fill_value=0)
piv.columns = piv.columns.to_flat_index().str.join('_')
# Encoding works as previously
encoder = OneHotEncoder(sparse_output=True)
piv_enc = encoder.fit_transform(piv)
piv_fin = pd.DataFrame.sparse.from_spmatrix(
piv_enc, columns=encoder.get_feature_names_out())
保存原始分类标签的方法可以在这篇文章中找到。