groupby.sum() pandas 或 scipy 中的稀疏矩阵:寻找性能
groupby.sum() sparse matrix in pandas or scipy: looking for performance
我有以下数据集df
:
import numpy.random
import pandas
cat = pandas.Series(numpy.random.random_integers(0,400,1000000))
ids = pandas.Series(numpy.random.random_integers(0,10000,1000000))
team = pandas.Series(numpy.random.random_integers(0,1,1000000))
df = pandas.concat([ids,cat,team],axis=1)
df.columns = ['ids','cat','team']
请注意,cat
列中只有 400 个不同的类别。因此,我想为机器学习分类准备数据集,即为从 0 到 400 的每个不同类别值创建一列,对于每一行,如果 id 具有相应的类别,则写入 1,否则写入 0。然后我的目标是按 ids
进行分组,并对每个类别列求和 1,如下所示:
df2 = pandas.get_dummies(df['cat'], sparse=True)
df2['ids'] = df['ids']
df3 = df2.groupby('ids').sum()
我的问题是 groupby.sum()
非常非常长,太长了(超过 30 分钟)。所以我需要一个不同的策略来进行计算。这是第二次尝试。
from sklearn import preprocessing
import numpy
text_encoder = preprocessing.OneHotEncoder(dtype=numpy.int)
X = text_encoder.fit_transform(df.drop(['team','ids'],axis=1).values).astype(int)
但是,X
是一个稀疏 scipy 矩阵。在这里我有两个选择:要么找到一种在这个稀疏 scipy 矩阵上有效地 groupby.sum()
的方法,要么我将它转换为带有 .toarray()
的真实 numpy 矩阵,如下所示:
X = X.toarray()
df2 = pandas.DataFrame(X)
df2['ids'] = df['ids']
df3 = df2.groupby('ids').sum()
现在的问题是由于 .toarray()
导致大量内存丢失。 groupby.sum()
肯定会占用大量内存。
所以我的问题是:对于groupby.sum()
,使用具有高效时间的稀疏矩阵是否有一种聪明的方法来解决我的问题?
编辑:实际上这是 pivot_table() 的工作,所以一旦创建了 df
:
df_final = df.pivot_table(cols='cat', rows='ids', aggfunc='count')
df_final.fillna(0, inplace = True)
记录但无用:根据我对问题的评论:
import numpy.random
import pandas
from sklearn import preprocessing
cat = pandas.Series(numpy.random.random_integers(0,400,1000000))
ids = pandas.Series(numpy.random.random_integers(0,10000,1000000))
team = pandas.Series(numpy.random.random_integers(0,1,1000000))
df = pandas.concat([ids,cat,team],axis=1)
df.columns = ['ids','cat','team']
df.sort('ids', inplace = True)
text_encoder = preprocessing.OneHotEncoder(dtype=numpy.int)
X = text_encoder.fit_transform(df.drop(['team','ids'],axis=1).values).astype(int)
se_size = df.groupby('ids').size()
ls_rows = []
row_ind = 0
for name, nb_lines in se_size.iteritems():
ls_rows.append(X[row_ind : row_ind + nb_lines,:].sum(0).tolist()[0])
row_ind += nb_lines
df_final = pandas.DataFrame(ls_rows,
index = se_size.index,
columns = text_encoder.active_features_)
我有以下数据集df
:
import numpy.random
import pandas
cat = pandas.Series(numpy.random.random_integers(0,400,1000000))
ids = pandas.Series(numpy.random.random_integers(0,10000,1000000))
team = pandas.Series(numpy.random.random_integers(0,1,1000000))
df = pandas.concat([ids,cat,team],axis=1)
df.columns = ['ids','cat','team']
请注意,cat
列中只有 400 个不同的类别。因此,我想为机器学习分类准备数据集,即为从 0 到 400 的每个不同类别值创建一列,对于每一行,如果 id 具有相应的类别,则写入 1,否则写入 0。然后我的目标是按 ids
进行分组,并对每个类别列求和 1,如下所示:
df2 = pandas.get_dummies(df['cat'], sparse=True)
df2['ids'] = df['ids']
df3 = df2.groupby('ids').sum()
我的问题是 groupby.sum()
非常非常长,太长了(超过 30 分钟)。所以我需要一个不同的策略来进行计算。这是第二次尝试。
from sklearn import preprocessing
import numpy
text_encoder = preprocessing.OneHotEncoder(dtype=numpy.int)
X = text_encoder.fit_transform(df.drop(['team','ids'],axis=1).values).astype(int)
但是,X
是一个稀疏 scipy 矩阵。在这里我有两个选择:要么找到一种在这个稀疏 scipy 矩阵上有效地 groupby.sum()
的方法,要么我将它转换为带有 .toarray()
的真实 numpy 矩阵,如下所示:
X = X.toarray()
df2 = pandas.DataFrame(X)
df2['ids'] = df['ids']
df3 = df2.groupby('ids').sum()
现在的问题是由于 .toarray()
导致大量内存丢失。 groupby.sum()
肯定会占用大量内存。
所以我的问题是:对于groupby.sum()
,使用具有高效时间的稀疏矩阵是否有一种聪明的方法来解决我的问题?
编辑:实际上这是 pivot_table() 的工作,所以一旦创建了 df
:
df_final = df.pivot_table(cols='cat', rows='ids', aggfunc='count')
df_final.fillna(0, inplace = True)
记录但无用:根据我对问题的评论:
import numpy.random
import pandas
from sklearn import preprocessing
cat = pandas.Series(numpy.random.random_integers(0,400,1000000))
ids = pandas.Series(numpy.random.random_integers(0,10000,1000000))
team = pandas.Series(numpy.random.random_integers(0,1,1000000))
df = pandas.concat([ids,cat,team],axis=1)
df.columns = ['ids','cat','team']
df.sort('ids', inplace = True)
text_encoder = preprocessing.OneHotEncoder(dtype=numpy.int)
X = text_encoder.fit_transform(df.drop(['team','ids'],axis=1).values).astype(int)
se_size = df.groupby('ids').size()
ls_rows = []
row_ind = 0
for name, nb_lines in se_size.iteritems():
ls_rows.append(X[row_ind : row_ind + nb_lines,:].sum(0).tolist()[0])
row_ind += nb_lines
df_final = pandas.DataFrame(ls_rows,
index = se_size.index,
columns = text_encoder.active_features_)