2013-08-16 15 views
5

mam pewne dane z eksperymentu, w ciągu każdej próby istnieją pewne pojedyncze wartości, otoczone NA „s, że chcę wypełnić do całego procesu:pandy: Wypełnienie brakujących wartości w grupie

df = pd.DataFrame({'trial': [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], 
    'cs_name': [np.nan, 'A1', np.nan, np.nan, np.nan, np.nan, 'B2', 
       np.nan, 'A1', np.nan, np.nan, np.nan]}) 
Out[177]: 
    cs_name trial 
0  NaN  1 
1  A1  1 
2  NaN  1 
3  NaN  1 
4  NaN  2 
5  NaN  2 
6  B2  2 
7  NaN  2 
8  A1  3 
9  NaN  3 
10  NaN  3 
11  NaN  3 

Jestem w stanie wypełnić te wartości w ciągu całego okresu próbnego, używając zarówno bfill(), jak i ffill(), ale zastanawiam się, czy istnieje lepszy sposób osiągnięcia tego.

df['cs_name'] = df.groupby('trial')['cs_name'].ffill() 
df['cs_name'] = df.groupby('trial')['cs_name'].bfill() 

oczekiwany wynik:

cs_name trial 
0  A1  1 
1  A1  1 
2  A1  1 
3  A1  1 
4  B2  2 
5  B2  2 
6  B2  2 
7  B2  2 
8  A1  3 
9  A1  3 
10  A1  3 
11  A1  3 

Odpowiedz

7

Alternatywnym podejściem jest użycie first_valid_index i transform:

In [11]: g = df.groupby('trial') 

In [12]: g['cs_name'].transform(lambda s: s.loc[s.first_valid_index()]) 
Out[12]: 
0  A1 
1  A1 
2  A1 
3  A1 
4  B2 
5  B2 
6  B2 
7  B2 
8  A1 
9  A1 
10 A1 
11 A1 
Name: cs_name, dtype: object 

To powinno być bardziej efektywne następnie używając ffill następnie bfill. ..

I to wykorzystać, aby zmienić kolumnę cs_name:

df['cs_name'] = g['cs_name'].transform(lambda s: s.loc[s.first_valid_index()]) 

Uwaga: Myślę, że byłoby miło wzmocnienie mieć sposób, aby pobrać pierwszy niezerowym obiekt należący do pand, w numpy to an open request, I don” t Myślę, że obecnie istnieje metoda (mógłbym się mylić!) ...

0

Jeśli chcesz uniknąć błędu, który pojawia się, gdy niektóre grupy zawierają tylko NaN, możesz wykonać następujące czynności (Zwróć uwagę, że zmieniłem plik df, aby są tylko Nan dla grupy mającej próbę = 1):

df = pd.DataFrame({'trial': [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,1,1], 
'cs_name': [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 'B2', np.nan, 
'A3', np.nan, np.nan, np.nan, np.nan,np.nan]}) 

g = data.groupby('trial') 

g['cs_name'].transform(lambda s: 'No values to aggregate' if 
    pd.isnull(s).all() == True else s.loc[s.first_valid_index()]) 

df['cs_name'] = g['cs_name'].transform(lambda s: 'No values to aggregate' if 
    pd.isnull(s).all() == True else s.loc[s.first_valid_index()])` 

W ten sposób wprowadzisz "Brak wartości do agregacji" (lub cokolwiek chcesz), gdy program znajdzie cały NaN dla konkretnej grupy, zamiast błędu.

Nadzieja to pomaga :)

Federico

Powiązane problemy