2015-03-27 3 views
2

Имея некоторые проблемы с заполнением NaNs. Я хочу взять столбец dataframe с несколькими NaN и заполнить их значением, полученным из таблицы поиска, на основе значения из другого столбца. (Вы могли бы признать мои данные из набора данных Titanic) ...Pandas fillna с поисковым столом

Pclass Age 
0 1  33 
1 3  24 
2 1  23 
3 2  NaN 
4 1  Nan 

Я хочу, чтобы заполнить NaN со значением из серии «pclass_lookup»:

pclass_lookup 
1  38.1 
2  29.4 
3  25.2 

Я пытался делать fillna с индексацией как:

df.Age.fillna(pclass_lookup[df.Pclass]), but it gives me an error of 
    ValueError: cannot reindex from a duplicate axis 

лямбды были тоже попробовать:

df.Age.map(lambda x: x if x else pclass_lookup[df.Pclass] 

но, похоже, это тоже не для заполнения. Неужели я полностью потерял лодку здесь? '

ответ

2

Во-первых, у вас есть значение Duff для строки 4, вы на самом деле есть строка' Нан ', который не совпадает с «NaN», поэтому даже если ваш код действительно работает, это значение никогда не будет заменено.

Так что вам нужно заменить это значение Дафф, а затем вы можете просто позвонить на карте, чтобы выполнить поиск на NaN значений:

In [317]: 

df.Age.replace('Nan', np.NaN, inplace=True) 
df.loc[df['Age'].isnull(),'Age'] = df['Pclass'].map(df1.pclass_lookup) 
df 
Out[317]: 
    Pclass Age 
0  1 33 
1  3 24 
2  1 23 
3  2 29.4 
4  1 38.1 

Timings

Для ФР с 5000 строками:

In [26]: 

%timeit df.loc[df['Age'].isnull(),'Age'] = df['Pclass'].map(df1.pclass_lookup) 
100 loops, best of 3: 2.41 ms per loop 
In [27]: 

%%timeit 
def remove_na(x): 
    if pd.isnull(x['Age']): 
     return df1[x['Pclass']] 
    else: 
     return x['Age'] 
df['Age'] =df.apply(remove_na, axis=1) 
1 loops, best of 3: 278 ms per loop 
In [28]: 

%%timeit 
nulls = df.loc[df.Age.isnull(), 'Pclass'] 
df.loc[df.Age.isnull(), 'Age'] = df1.loc[nulls].values 
100 loops, best of 3: 3.37 ms per loop 

Таким образом, вы видите здесь, которые применяются, поскольку они повторяют шкалы по шкале по сравнению с другими t wo, которые были векторизованы, но map по-прежнему является самым быстрым.

+0

Все три ответа работали отлично. Функция vrajs5 довольно проста. Этот ответ, хотя и плотный, чтобы посмотреть, был именно тем, что я пытался сделать. пс. Извините за типографию Nan – zampy

+0

Вы, вероятно, найдете, что карта вызова, подобная этому, будет самым быстрым методом – EdChum

0

должно работать для вас:

df = pd.DataFrame() 
df['Pclass'] = [1,3,1,2,1] 
df['Age'] = [33,24,23,None, None] 
df 
    Pclass Age 
0  1 33 
1  3 24 
2  1 23 
3  2 NaN 
4  1 NaN 

pclass_lookup = pd.Series([38.1,29.4,25.2], index = range(1,4)) 
pclass_lookup 
1 38.1 
2 29.4 
3 25.2 
dtype: float64 

def remove_na(x): 
    if pd.isnull(x['Age']): 
     return pclass_lookup[x['Pclass']] 
    else: 
     return x['Age'] 
df['Age'] =df.apply(remove_na, axis=1) 

    Pclass Age 
0  1 33.0 
1  3 24.0 
2  1 23.0 
3  2 29.4 
4  1 38.1 
1

Опираясь на отклик @ vrajs5:

# Create dummy data 
df = pd.DataFrame() 
df['Pclass'] = [1,3,1,2,1] 
df['Age'] = [33,24,23,None, None] 
pclass_lookup = pd.Series([38.1,29.4,25.2], index = range(1,4)) 

# Solution: 
nulls = df.loc[df.Age.isnull(), 'Pclass'] 
df.loc[df.Age.isnull(), 'Age'] = pclass_lookup.loc[nulls].values 

>>> df 
    Pclass Age 
0  1 33.0 
1  3 24.0 
2  1 23.0 
3  2 29.4 
4  1 38.1 
Смежные вопросы