从Pandas DataFrame中提取数组(列名,数据)

时间:2015-01-15 05:04:06

标签: python pandas gensim

这是Stack Overflow的第一个问题。

我有像这样的Pandas DataFrame。

        a   b   c   d
one     0   1   2   3
two     4   5   6   7
three   8   9   0   1
four    2   1   1   5
five    1   1   8   9

我想提取数据为1的列名和数据对,每个索引在数组中是分开的。

[ [(b,1.0)], [(d,1.0)], [(b,1.0),(c,1.0)], [(a,1.0),(b,1.0)] ]

我想使用python库的gensim,它需要语料库作为这种形式。

有没有聪明的方法可以做到这一点或者从pandas数据中应用gensim?

2 个答案:

答案 0 :(得分:1)

许多gensim函数接受numpy数组,因此可能有更好的方法......

In [11]: is_one = np.where(df == 1)

In [12]: is_one
Out[12]: (array([0, 2, 3, 3, 4, 4]), array([1, 3, 1, 2, 0, 1]))

In [13]: df.index[is_one[0]], df.columns[is_one[1]]
Out[13]:
(Index([u'one', u'three', u'four', u'four', u'five', u'five'], dtype='object'),
 Index([u'b', u'd', u'b', u'c', u'a', u'b'], dtype='object'))

要对每行进行分组,您可以使用iterrows:

from itertools import repeat

In [21]: [list(zip(df.columns[np.where(row == 1)], repeat(1.0)))
          for label, row in df.iterrows()
          if 1 in row.values]  # if you don't want empty [] for rows without 1
Out[21]:
[[('b', 1.0)],
 [('d', 1.0)],
 [('b', 1.0), ('c', 1.0)],
 [('a', 1.0), ('b', 1.0)]]

在python 2中,由于zip返回列表,因此不需要list

答案 1 :(得分:0)

另一种方式是

In [1652]: [[(c, 1) for c in x[x].index] for _, x in df.eq(1).iterrows() if x.any()]
Out[1652]: [[('b', 1)], [('d', 1)], [('b', 1), ('c', 1)], [('a', 1), ('b', 1)]]