Python 如何创建虚拟变量,然后使用scikit learn进行聚合?

Python 如何创建虚拟变量,然后使用scikit learn进行聚合?,python,pandas,scikit-learn,dummy-variable,one-hot-encoding,Python,Pandas,Scikit Learn,Dummy Variable,One Hot Encoding,我知道使用pandas软件包很容易实现,但是因为它太稀疏和太大(170000 x 5000),最后我需要使用sklearn再次处理数据,我想知道是否有办法使用sklearn。我尝试了一个热编码器,但我坚持把假人和“id”联系起来 df = pd.DataFrame({'id': [1, 1, 2, 2, 3, 3], 'item': ['a', 'a', 'c', 'b', 'a', 'b']}) id item 0 1 a 1 1 a 2 2 c 3

我知道使用pandas软件包很容易实现,但是因为它太稀疏和太大(170000 x 5000),最后我需要使用sklearn再次处理数据,我想知道是否有办法使用sklearn。我尝试了一个热编码器,但我坚持把假人和“id”联系起来

df = pd.DataFrame({'id': [1, 1, 2, 2, 3, 3], 'item': ['a', 'a', 'c', 'b', 'a', 'b']})

   id item
0   1    a
1   1    a
2   2    c
3   2    b
4   3    a
5   3    b

dummy = pd.get_dummies(df, prefix='item', columns=['item'])
dummy.groupby('id').sum().reset_index()

   id  item_a  item_b  item_c
0   1       2       0       0
1   2       0       1       1
2   3       1       1       0
更新:

现在我在这里,“id”丢失了,那么怎么做呢

lab = sklearn.preprocessing.LabelEncoder()
labels = lab.fit_transform(np.array(df.item))
enc = sklearn.preprocessing.OneHotEncoder()
dummy = enc.fit_transform(labels.reshape(-1,1))

dummy.todense()

matrix([[ 1.,  0.,  0.],
        [ 1.,  0.,  0.],
        [ 0.,  0.,  1.],
        [ 0.,  1.,  0.],
        [ 1.,  0.,  0.],
        [ 0.,  1.,  0.]])

OneHotEncoder需要整数,所以这里有一种将项目映射到唯一整数的方法。因为映射是一对一的,所以我们也可以反转此字典

import pandas as pd
from sklearn.preprocessing import OneHotEncoder

df = pd.DataFrame({'ID': [1, 1, 2, 2, 3, 3], 
                   'Item': ['a', 'a', 'c', 'b', 'a', 'b']})

mapping = {letter: integer for integer, letter in enumerate(df.Item.unique())}
reverse_mapping = {integer: letter for letter, integer in mapping.iteritems()}

>>> mapping
{'a': 0, 'b': 2, 'c': 1}

>>> reverse_mapping
{0: 'a', 1: 'c', 2: 'b'}
现在创建一个OneHotEncoder并映射您的值

hot = OneHotEncoder()
h = hot.fit_transform(df.Item.map(mapping).values.reshape(len(df), 1))
>>> h
<6x3 sparse matrix of type '<type 'numpy.float64'>'
    with 6 stored elements in Compressed Sparse Row format>
>>> h.toarray()
array([[ 1.,  0.,  0.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  0.,  1.]])
从数据中,您可以看到数据框中的值
c
位于第三行(索引值为2)。这已映射到
c
,您可以从反向映射中看到,它位于中间列。它也是矩阵中值中包含一个值的唯一值,确认结果。

除此之外,我不确定你会被困在哪里。如果您仍然有问题,请澄清

要连接ID值,请执行以下操作:

>>> np.concatenate((df.ID.values.reshape(len(df), 1), h.toarray()), axis=1)
array([[ 1.,  1.,  0.,  0.],
       [ 1.,  1.,  0.,  0.],
       [ 2.,  0.,  1.,  0.],
       [ 2.,  0.,  0.,  1.],
       [ 3.,  1.,  0.,  0.],
       [ 3.,  0.,  0.,  1.]])
要保持阵列稀疏,请执行以下操作:

from scipy.sparse import hstack, lil_matrix

id_vals = lil_matrix(df.ID.values.reshape(len(df), 1))
h_dense = hstack([id_vals, h.tolil()])
>>> type(h_dense)
scipy.sparse.coo.coo_matrix

>>> h_dense.toarray()
array([[ 1.,  1.,  0.,  0.],
       [ 1.,  1.,  0.,  0.],
       [ 2.,  0.,  1.,  0.],
       [ 2.,  0.,  0.,  1.],
       [ 3.,  1.,  0.,  0.],
       [ 3.,  0.,  0.,  1.]])

如果将来有人需要推荐人,我会把我的解决方案放在这里。 我使用了scipy稀疏矩阵

首先,进行分组并计算记录数

df = df.groupby(['id','item']).size().reset_index().rename(columns={0:'count'})
这需要一些时间,但不是几天

然后使用pivot表,我找到了一个解决方案

然后调用函数

result = to_sparse_pivot(df, 'id', 'item', 'count')

您能按显示的方式在数据帧中进行分类,然后使用as_matrix()方法转换为numpy数组表示吗?@SteveMisuta是的,我能做到。你能解释一下原因吗?@Chen你有没有弄明白?@Afflatus,我想我最后转向了scipy稀疏矩阵。首先使用
df.groupby(['id','item']).size().reset_index().rename(columns={0:'count'})
,这需要一些时间,但不是几天。然后使用pivot表,可以找到它。它满足了我当时的需要。希望有帮助,任何评论,让我知道。谢谢!!!这非常有帮助。谢谢你的回答,根据那些id,我被困在聚合上了。有关详细信息,请参见原始问题中的更新。您想要的输出是什么?类似于我在原始问题中显示的
dummy.groupby('id').sum().reset_index()
后面的输出。必须是稀疏矩阵,否则会占用太多内存。顺便说一句,我用真实的数据集尝试了熊猫的方法,而
groupby
步骤需要几天,所以我在完成之前就放弃了。
from scipy.sparse import csr_matrix

def to_sparse_pivot(df, id, item, count):
    id_u = list(df[id].unique())
    item_u = list(np.sort(df[item].unique()))
    data = df[count].tolist()
    row = df[id].astype('category', categories=id_u).cat.codes
    col = df[item].astype('category', categories=item_u).cat.codes
    return csr_matrix((data, (row, col)), shape=(len(id_u), len(item_u)))
result = to_sparse_pivot(df, 'id', 'item', 'count')