2016-10-28 4 views
4

Ich möchte NaN-Werte in einer DataFrame (df) -Spalte (var4) basierend auf einer Steuertabelle (fillna_mean) mit Spalte Mittelwert und Var1 als Index füllen. Im Dataframe möchte ich sie passend für var1.Python pandas Dataframe Füllung NaN mit anderen Serie

Ich habe versucht, dies mit fillna zu tun, aber ich bekomme es nicht die ganze Zeit arbeiten. Wie mache ich das auf intelligente Weise, indem ich df.var1 als Index verwende, der fillna_mean.var1 entspricht?

df:

df = pd.DataFrame({'var1' : list('a' * 3) + list('b' * 2) + list('c' * 4) + list('d' * 3) 
     ,'var2' : [i for i in range(12)] 
     ,'var3' : list(np.random.randint(100, size = 12)) 
     ,'var4' : [1, 2, np.nan, 3, 2, np.nan, 1, 34, np.nan, np.nan, 12, 12] 
    }) 

fillna_mean:

fillna = pd.DataFrame({'var1' : ['a', 'b', 'c', 'd'], 
         'mean' : [1, 3.5, 6.5, 10]}) 

End Ergebnis ist dieses:

 
var1 var2 var3 var4 
a 0 69 1.0 
a 1 17 2.0 
a 2 83 1.0 
b 3 12 3.0 
b 4 36 2.0 
c 5 68 6.5 
c 6 13 1.0 
c 7 30 34.0 
c 8 23 6.5 
d 9 82 10.0 
d 10 32 12.0 
d 11 19 12.0 

Vielen Dank im Voraus für die Eingabe!

/swepab

Antwort

3

können Sie boolean indexing in Verbindung mit .map() Methode verwenden:

In [178]: fillna.set_index('var1', inplace=True) 

In [179]: df.loc[df.var4.isnull(), 'var4'] = df.loc[df.var4.isnull(), 'var1'].map(fillna['mean']) 

In [180]: df 
Out[180]: 
    var1 var2 var3 var4 
0  a  0 40 1.0 
1  a  1 97 2.0 
2  a  2 34 1.0 
3  b  3  6 3.0 
4  b  4 19 2.0 
5  c  5 47 6.5 
6  c  6 65 1.0 
7  c  7 29 34.0 
8  c  8 48 6.5 
9  d  9 88 10.0 
10 d 10 40 12.0 
11 d 11 23 12.0 

Erläuterung:

In [184]: df.loc[df.var4.isnull()] 
Out[184]: 
    var1 var2 var3 var4 
2 a  2 75 NaN 
5 c  5 75 NaN 
8 c  8 44 NaN 
9 d  9 34 NaN 

In [185]: df.loc[df.var4.isnull(), 'var1'] 
Out[185]: 
2 a 
5 c 
8 c 
9 d 
Name: var1, dtype: object 

In [186]: df.loc[df.var4.isnull(), 'var1'].map(fillna['mean']) 
Out[186]: 
2  1.0 
5  6.5 
8  6.5 
9 10.0 
Name: var1, dtype: float64 

UPDATE: von Pandas beginnen 0.20.1 the .ix indexer is deprecated, in favor of the more strict .iloc and .loc indexers.

+0

Reine Schönheit, daß man - soliden Sieg! Tausend Dank! – swepab

2

schnellere Ergebnisse with combine_first, und Sie nicht die Mühe Sie ungleich NULL Daten herauszufiltern:

fillna.set_index('var1', inplace=True) 

df.var4 = df.var4.combine_first(df.var1.map(fillna['mean'])) 
Verwandte Themen