Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将数据帧转换为具有混合列类型的稀疏矩阵?_Python_Pandas_Scipy_Scikit Learn_Sparse Matrix - Fatal编程技术网

Python 如何将数据帧转换为具有混合列类型的稀疏矩阵?

Python 如何将数据帧转换为具有混合列类型的稀疏矩阵?,python,pandas,scipy,scikit-learn,sparse-matrix,Python,Pandas,Scipy,Scikit Learn,Sparse Matrix,我有以下格式的数据框: df: key f1 f2 k1 10 a, b, c k2 20 b, d k3 15 NaN key f1 f2.a f2.b f2.c f2.d k1 10 1 1 1 0 k2 20 0 1 0 1 k3 15 0 0 0 0 f2列有一袋单词作为值。我想把这个数据帧转换成一个稀疏矩阵,因为f

我有以下格式的数据框:

df:

key   f1    f2
k1    10    a, b, c
k2    20    b, d
k3    15    NaN
key    f1  f2.a  f2.b  f2.c  f2.d
k1     10   1     1     1     0
k2     20   0     1     0     1
k3     15   0     0     0     0
f2列有一袋单词作为值。我想把这个数据帧转换成一个稀疏矩阵,因为f2中的不同单词可以达到几千个。我期望的最终结果如下:

df:

key   f1    f2
k1    10    a, b, c
k2    20    b, d
k3    15    NaN
key    f1  f2.a  f2.b  f2.c  f2.d
k1     10   1     1     1     0
k2     20   0     1     0     1
k3     15   0     0     0     0
我可以想出如何独立地创建一个稀疏矩阵,只需要在key和f2字段之外。我首先熔化列f2,因此得到以下数据帧:

df1:
key  f2
k1   a
k1   b
k1   c
k2   b
k2   d
然后我对f2进行编码,并使用sklearn.preprocessing包中的LabelEncoder对f2进行编码。然后我创建一个稀疏矩阵,如下所示:

df1['trainrow'] = np.arrange(df1.shape[0])
sparse.csr_matrix((np.ones(df1.shape[0], (df1.trainrow, df1.f2_encoded)))
from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer()
df2 = vectorizer.fit_transform(df['f2'].str.replace(' ',''))
这将通过对字段f2进行一次热编码来创建稀疏矩阵。但我不确定如何将其与数值字段f1连接起来

您可以与和一起使用:

在非常大的不同值中,
get_dummies
非常慢,您可以使用自定义函数
f

def f(category_list):
    n_categories = len(category_list)
    return pd.Series(dict(zip(category_list, [1]*n_categories)))

#remove NaN rows and create list of values by split
df1 = df.f2.dropna().str.split(', ').apply(f).add_prefix('f2.')
df2 = pd.concat([df[['key','f1']], df1], axis=1)
#replace NaN to 0 by position from 3.column to end of df
df2.iloc[:, 2: ] = df2.iloc[:, 2: ].fillna(0).astype(int)
print (df2)
  key  f1  f2.a  f2.b  f2.c  f2.d
0  k1  10     1     1     1     0
1  k2  20     0     1     0     1
2  k3  15     0     0     0     0
计时

In [256]: %timeit s.str.get_dummies(sep=', ')
1 loop, best of 3: 1min 16s per loop

In [257]: %timeit (s.dropna().str.split(', ').apply(f).fillna(0).astype(int))
1 loop, best of 3: 2.95 s per loop
np.random.seed(100)
s = pd.DataFrame(np.random.randint(10000, size=(1000,1000))).astype(str).apply(', '.join, axis=1)
print (s)


df2 = s.str.get_dummies(sep=', ')
print (df2)

def f(category_list):
    n_categories = len(category_list)
    return pd.Series(dict(zip(category_list, [1]*n_categories)))

print (s.dropna().str.split(', ').apply(f).fillna(0).astype(int))
计时代码

In [256]: %timeit s.str.get_dummies(sep=', ')
1 loop, best of 3: 1min 16s per loop

In [257]: %timeit (s.dropna().str.split(', ').apply(f).fillna(0).astype(int))
1 loop, best of 3: 2.95 s per loop
np.random.seed(100)
s = pd.DataFrame(np.random.randint(10000, size=(1000,1000))).astype(str).apply(', '.join, axis=1)
print (s)


df2 = s.str.get_dummies(sep=', ')
print (df2)

def f(category_list):
    n_categories = len(category_list)
    return pd.Series(dict(zip(category_list, [1]*n_categories)))

print (s.dropna().str.split(', ').apply(f).fillna(0).astype(int))

我已经找到了解决这个问题的最佳方法,因此将其作为我未来的参考答案,并为其他人的利益发布:

由于数据量巨大,我只能使用稀疏矩阵

第一步是将文字包转换为矢量化格式。我使用了CountVectorizer(感谢@MaxU),如下所示:

df1['trainrow'] = np.arrange(df1.shape[0])
sparse.csr_matrix((np.ones(df1.shape[0], (df1.trainrow, df1.f2_encoded)))
from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer()
df2 = vectorizer.fit_transform(df['f2'].str.replace(' ',''))
我希望忽略空格并使用逗号作为强制分隔符。我不知道该怎么做,所以我替换了空格,否则矢量器会在空格处拆分单词

这将df1创建为稀疏矩阵

然后将另一个字段f1转换为不同的稀疏矩阵:

df1 = csr_matrix(df[['f1']].fillna(0))
然后使用hstack将这两种方法结合起来:
sparseDF=hstack((df1,df2),format='csr')

此解决方案在字段f2中的不同值数量有限的情况下非常有效。但我在字段中有大约20k个不同的值,因此需要花费很长时间。有什么建议我可以处理这么大的数据集吗?(出于同样的原因,我尝试使用稀疏矩阵)我将使用
sklearn.feature\u extraction.text
中的
CountVectorizer
来完成这项任务-它应该非常有用faster@MaxU我面临一个计数向量器的问题。我的单词包用逗号隔开,每个单词可能都有空格。我不希望矢量器将它们视为不同的功能。我们能控制这一切吗?提前谢谢。我用你的样本数据尝试你的答案,但它对我不起作用。有什么问题吗?它返回
ValueError:空词汇表;可能文档中只包含停止词
,很抱歉回复太晚。我试过这个方法,但似乎它对单个字母不起作用。你能试着多加一个字母(aa,bb,cc而不是a,b,c)吗?我的实际用例有文字,所以我没有意识到它与我提供的示例不起作用。是的,这是一个问题。但是现在我得到了error
ValueError:blocks[0,:]在
sparseDF=hstack((df1,df2),format='csr')
中具有不兼容的行维度。输出为矩阵,带有
0
1
?@jezrael我已修改了df1创建步骤。我们不应该调用df['f1'],而应该使用df['f1']],这样它将返回数据帧,而不仅仅是列。请让我知道,如果它仍然抛出任何错误。谢谢你的忍耐。我刚刚开始使用Python进行数据分析。