将pandas系列转换为可迭代的迭代

时间:2017-07-24 20:37:45

标签: python pandas scikit-learn

我正在尝试在sklearn中使用MultiLabelBinarizer。我有一个熊猫系列,我想把这个系列作为MultiLabelBinarizer的拟合函数的输入。但是,我发现MultiLabelBinarizer适合需要表单iterable of iterables的输入。我不知道如何将熊猫系列转换为所需的类型。

import pandas as pd
from sklearn.preprocessing import MultiLabelBinarizer

data = pd.read_csv("somecsvFile")
y = pd.DataFrame(data['class'])

mlb = MultiLabelBinarizer()
y = mlb.fit(???)

我尝试将它转换为numpy数组,尝试使用pandas的iter功能,但似乎没有任何工作。

请以某种方式建议我。

由于

Edit1:print(data['class'].head(10))的输出为:

0        func
1        func
2        func
3    non func
4        func
5        func
6    non func
7    non func
8    non func
9        func
Name: status_group, dtype: object

2 个答案:

答案 0 :(得分:6)

如何解决MultiLabelBinarizer's fit needs an input of form iterable of iterables

这一事实
In [8]: df
Out[8]:
      class
0      func
1      func
2      func
3  non func
4      func
5      func
6  non func
7  non func
8  non func
9      func

In [10]: import pandas as pd
    ...: from sklearn.preprocessing import MultiLabelBinarizer

In [11]: y = df['class'].str.split(expand=False)   # <--- NOTE !!!

In [12]: mlb = MultiLabelBinarizer()
    ...: y = mlb.fit_transform(y)
    ...:

In [13]: y
Out[13]:
array([[1, 0],
       [1, 0],
       [1, 0],
       [1, 1],
       [1, 0],
       [1, 0],
       [1, 1],
       [1, 1],
       [1, 1],
       [1, 0]])

更新: as proposed by @unutbu you can use pd.get_dummies()

In [21]: pd.get_dummies(df['class'])
Out[21]:
   func  non func
0     1         0
1     1         0
2     1         0
3     0         1
4     1         0
5     1         0
6     0         1
7     0         1
8     0         1
9     1         0

答案 1 :(得分:3)

你问的是什么

MultiLabelBinarizer采用可迭代的迭代次数。

df['class']是一个可迭代的,因为值是一维的。你可以使它成为二维的并解决你的问题。

mlb.fit_transform(df[['class']].values)
# equivalently
# mlb.fit_transform(df['class'].values[:, None])

array([[1, 0],
       [1, 0],
       [1, 0],
       [0, 1],
       [1, 0],
       [1, 0],
       [0, 1],
       [0, 1],
       [0, 1],
       [1, 0]])

仔细观察
此示例具有3个唯一值,将生成3列。

mlb.fit_transform([
    ['a'],
    ['b'],
    ['a'],
    ['c']
])

array([[1, 0, 0],
       [0, 1, 0],
       [1, 0, 0],
       [0, 0, 1]])

但是,我们也可以传递非统一子列表

mlb.fit_transform([
    ['a'],
    ['b', 'a'],
    ['a'],
    ['c', 'b']
])

array([[1, 0, 0],
       [1, 1, 0],
       [1, 0, 0],
       [0, 1, 1]])

虽然你的情况并没有利用这个,但这就是为什么它需要迭代的迭代,以便它可以做我刚刚展示的。

我做了什么

因为MultiLabelBinarizer可以做的比我们需要的多,所以我们可以用更清晰的工具做更好的事情

f, u = pd.factorize(df['class'].values)
np.eye(u.size, dtype=int)[f]

array([[1, 0],
       [1, 0],
       [1, 0],
       [0, 1],
       [1, 0],
       [1, 0],
       [0, 1],
       [0, 1],
       [0, 1],
       [1, 0]])

比较时间

%timeit mlb.fit_transform(df['class'].values[:, None])

10000 loops, best of 3: 191 µs per loop

%%timeit
f, u = pd.factorize(df['class'].values)
np.eye(u.size, dtype=int)[f]

10000 loops, best of 3: 68.8 µs per loop