2016-09-17 1 views
2

schrieb ich die folgende Funktion mehrere Spalten eines Datenrahmens in numerische Werte zu konvertieren:Pandas: Fehler auf DataFrame.unstack

def factorizeMany(data, columns): 
    """ Factorize a bunch of columns in a data frame""" 
    data[columns] = data[columns].stack().rank(method='dense').unstack() 
    return data 

es wie dieses

trainDataPre = factorizeMany(trainDataMerged.fillna(0), columns=["char_{0}".format(i) for i in range(1,10)]) 
Aufruf gibt mir einen Fehler. Ich weiß nicht, wo ich nach der Ursache suchen soll, möglicherweise nach falschem Input?

--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-14-357f8a4b2ef8> in <module>() 
     1 #trainDataPre = trainDataMerged.drop(["people_id", "activity_id", "date"], axis=1) 
     2 #trainDataPre = trainDataMerged.fillna(0) 
----> 3 trainDataPre = mininggear.factorizeMany(trainDataMerged.fillna(0), columns=["char_{0}".format(i) for i in range(1,10)]) 

/Users/cls/Dropbox/Datengräber/Kaggle/RedHat/mininggear.py in factorizeMany(data, columns) 
    15 def factorizeMany(data, columns): 
    16  """ Factorize a bunch of columns in a data frame""" 
---> 17  data[columns] = data[columns].stack().rank(method='dense').unstack() 
    18  return data 
    19 

/usr/local/lib/python3.5/site-packages/pandas/core/series.py in unstack(self, level, fill_value) 
    2041   """ 
    2042   from pandas.core.reshape import unstack 
-> 2043   return unstack(self, level, fill_value) 
    2044 
    2045  # ---------------------------------------------------------------------- 

/usr/local/lib/python3.5/site-packages/pandas/core/reshape.py in unstack(obj, level, fill_value) 
    405  else: 
    406   unstacker = _Unstacker(obj.values, obj.index, level=level, 
--> 407        fill_value=fill_value) 
    408   return unstacker.get_result() 
    409 

/usr/local/lib/python3.5/site-packages/pandas/core/reshape.py in __init__(self, values, index, level, value_columns, fill_value) 
    90 
    91   # when index includes `nan`, need to lift levels/strides by 1 
---> 92   self.lift = 1 if -1 in self.index.labels[self.level] else 0 
    93 
    94   self.new_index_levels = list(index.levels) 

AttributeError: 'Index' object has no attribute 'labels' 
+0

Könnten Sie eine Probe Ihres 'trainDataMerged' Datenrahmen zur Verfügung stellen? –

+0

@ AlbertoGarcia-Raboso Veröffentlichen Sie eine riesige CSV-Zeichenfolge? Was ist, wenn dieses Beispiel nicht die Daten enthält, die den Fehler verursachen? Wie die folgende Antwort zeigt, kann diese Frage mit einigen Einsichten beantwortet werden. – clstaudt

Antwort

1

Der Fehler ist aufgrund der Tatsache, dass Sie versuchen, den rank Betrieb auf der Teilmenge des Datenrahmen auszuführen sowohl numerischen und kategorialen/String-Wert enthält, die durch die NaN's in dem Datenrahmen mit 0 füllen und dieser Funktion aufrufen .

Betrachten wir diesen Fall:

df = pd.DataFrame({'char_1': ['cat', 'dog', 'buffalo', 'cat'], 
        'char_2': ['mouse', 'tiger', 'lion', 'mouse'], 
        'char_3': ['giraffe', np.NaN, 'cat', np.NaN]}) 
df 

Image

df = df.fillna(0) 
df[['char_3']].stack().rank() 
Series([], dtype: float64) 

Also, Sie ausführen grundsätzlich die unstack Betrieb auf eine leere Reihe, die nicht ist, was Sie schließlich tun wollte.

Besser ist es, diese Art und Weise zu tun, um weitere Komplikationen zu vermeiden:

def factorizeMany(data, columns): 
    """ Factorize a bunch of columns in a data frame""" 
    stacked = data[columns].stack(dropna=False) 
    data[columns] = pandas.Series(stacked.factorize()[0], index=stacked.index).unstack() 
    return data 
+0

Sorry, die Reihenfolge der 'faktorizeMany' und' fillna' alleine zu ändern, erzeugt immer noch den Fehler. – clstaudt

+1

Die "Stack" -Methode löscht außerdem alle standardmäßig vorhandenen 'NaN'-Werte. Sie könnten also 'stack (dropna = False)' verwenden, um sie zur 'faktorisieren' Methode zu füttern, die sie als -1 markiert. –