2017-07-24 4 views
4

Ich versuche MultiLabelBinarizer in sklearn zu verwenden. Ich habe eine Pandas-Serie und möchte diese Serie als Eingabe für die Fit-Funktion MultiLabelBinarizer eingeben. Ich sehe jedoch, dass die Anpassung von MultiLabelBinarizer eine Eingabe von Formular iterable of iterables benötigt. Ich bin mir nicht sicher, wie ich die Pandas-Serie in den gewünschten Typ konvertieren kann.Konvertieren Pandas-Serie zu iterierbaren 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(???) 

Ich habe versucht, es zu numpy Array zu konvertieren, versuchte mit Iter-Funktion von Pandas, aber nichts scheint zu funktionieren.

Bitte schlagen Sie mir einen Weg vor.

Dank

Edit1: Ausgabe von print(data['class'].head(10)) ist:

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 
+0

Wie sieht Ihr Datenrahmen aus? Diese Lösung ist einfach, ich muss nur wissen, welche Spalten Ihr df hat. –

+0

Können Sie eine Ausgabe von 'print (data ['class']. Head (10))'? – MaxU

+0

@ cᴏʟᴅsᴘᴇᴇᴅ - Bearbeitete Frage, um die Ausgabe des Kopfes hinzuzufügen. –

Antwort

6

Wie die Tatsache umgehen, dass 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]]) 

UPDATE: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

Puh!Du hast das Problem gelöst. +1 –

+0

@ cᴏʟᴅsᴘᴇᴇᴅ, ja, diese Fehlermeldung ist nicht 100% klar. Vielen Dank! :) – MaxU

+2

Dies scheint 'non func' zu interpretieren, um zwei Label zu sein: sowohl' non 'als auch' func'. Wenn das OP möchte, dass "non func" ein Label ist, das von "func" verschieden ist, dann würden "pd.get_dummies (df ['class']). Values" ausreichen. – unutbu

3

Was Sie

fragte

MultiLabelBinarizer nimmt eine iterable von Iterables.

df['class'] ist ein iterable darin, dass die Werte eindimensional sind. Sie können es zweidimensional machen und Ihr Problem lösen.

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

Ein genauerer Blick
Dieses Beispiel einen 3 eindeutigen Werte hat und 3 Spalten erzeugen.

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

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

können wir jedoch nicht einheitliche Unterlisten übergeben als auch

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

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

Obwohl Ihr Fall nicht nutzen diese, ist der Grund, warum es eine iterable von Iterables nimmt, so dass es kann tun, was ich gerade gezeigt habe.


Was würde ich tun, anstatt

Da MultiLabelBinarizer kann mehr tun, als wir brauchen, können wir in der Lage sein, etwas besser mit einem schärferen Werkzeug

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

Vergleich zu tun Timing

%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 
+0

Danke für die klare Beschreibung. Ich habe die Idee jetzt klar verstanden. –

Verwandte Themen