簡體   English   中英

如何將數據框轉換為具有混合列類型的稀疏矩陣?

[英]How to convert a dataframe to sparse matrix with mixed column types?

我有以下格式的數據框:

df:

key   f1    f2
k1    10    a, b, c
k2    20    b, d
k3    15    NaN

f2列具有一袋單詞作為值。 我想將此數據幀轉換為稀疏矩陣,因為f2中的不同單詞多達數千個。 我期望的最終結果具有以下格式:

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)))

這通過對字段f2進行單次熱編碼來創建稀疏矩陣。 但是我不確定如何將其與數值字段f1連接起來。

您可以將concatstr.get_dummiesadd_prefix

df = pd.concat([df[['key','f1']], df.f2.str.get_dummies(sep=', ').add_prefix('f2.')], axis=1)
print (df)
  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

在很大的不同值中, 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))

我已經找到了解決此問題的最佳方法,因此將其發布為我將來的參考和他人的答案:

由於數據量巨大,我只需要使用稀疏矩陣。

第一步是將單詞袋轉換為矢量格式。 我已經使用了CountVectorizer(為此,感謝@MaxU):

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')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM