使用pandas

时间:2017-06-07 09:35:37

标签: python pandas categorical-data one-hot-encoding

Hej,我正在尝试对可能属于多个类别的项目进行矢量化并将它们放入pandas数据帧中。我已经想出了一个解决方案,但速度很慢。所以这就是我正在做的事情:

这就是我的数据的样子:

data = {
    'A':['c1','c2','c3'],
    'B':['c4','c5','c2'],
    'C':['c2','c1','c4']
}

我有三个项目(A-C)属于五个不同的类别(c1-c5)。

所以我创建了一个空数据帧,迭代项目将它们转换为具有正确索引的布尔系列对象并附加它们:

df = pd.SparseDataFrame()
for k, v in data.items():
    s = pd.Series(np.ones_like(v, dtype=bool), index=v, name=k)
    df = df.append(s)

我的结果如下:

Resulting Dataframe

我对这个结果感到满意,但我的真实数据有大约20万个类别,这使得这种方法非常缓慢。你有什么建议如何加快?

备注:提取所有类别并将其作为列传递到空的Dataframe中并不起作用:

df = pd.SparseDataFrame(columns=all_categories)

2 个答案:

答案 0 :(得分:1)

您可以尝试(source):

df = pd.DataFrame.from_dict(data, orient='index')

然后

res = df.stack().reset_index().groupby(['level_0', 0]).size().unstack()

最后,您可以将输出转换为SparseDataFrame

result = pd.SparseDataFrame(res)

使用df.stack()

A  0    c1
   1    c2
   2    c3
B  0    c4
   1    c5
   2    c2
C  0    c2
   1    c1
   2    c4

然后你执行reset_index

  level_0  level_1   0
0       A        0  c1
1       A        1  c2
2       A        2  c3
3       B        0  c4
4       B        1  c5
5       B        2  c2
6       C        0  c2
7       C        1  c1
8       C        2  c4

您可以将列名更改为更清晰。 按方法分组计数:

level_0  0
A        c1    1
         c2    1
         c3    1
B        c2    1
         c4    1
         c5    1
C        c1    1
         c2    1
         c4    1

最后:

0         c1   c2   c3   c4   c5
level_0
A        1.0  1.0  1.0  NaN  NaN
B        NaN  1.0  NaN  1.0  1.0
C        1.0  1.0  NaN  1.0  NaN

答案 1 :(得分:1)

考虑以下内存保存方法:

In [143]: df = pd.DataFrame([' '.join(data[k]) for k in data.keys()],
                            index=data.keys(),
                            columns=['text'])

In [144]: df
Out[144]:
       text
C  c2 c1 c4
A  c1 c2 c3
B  c4 c5 c2

In [145]: from sklearn.feature_extraction.text import CountVectorizer

In [146]: cv = CountVectorizer()

In [147]: df = pd.SparseDataFrame(cv.fit_transform(df['text']),
                                  columns=cv.get_feature_names(),
                                  index=df.index)

In [148]: df
Out[148]:
    c1  c2   c3   c4   c5
C  1.0   1  NaN  1.0  NaN
A  1.0   1  1.0  NaN  NaN
B  NaN   1  NaN  1.0  1.0


In [149]: df.memory_usage()
Out[149]:
Index    80
c1       16
c2       24
c3        8
c4       16
c5        8
dtype: int64