2017-02-11 7 views
3

Использование «bfill» или «ffill» для элемента groupby является тривиальным, но что, если вам нужно заполнить na определенным значением во втором столбце на основе условие в третьей колонке?(pandas) Fill NaN на основе группового и столбцового условий

Например:

>>> df=pd.DataFrame({'date':['01/10/2017', '02/09/2017', '02/10/2016','01/10/2017', '01/11/2017', '02/10/2016'], 'a':[1,1,1,2,2,2], 'b':[4,np.nan,6, 5, np.nan, 7]}) 
>>> df 
    a b  date 
0 1 4.0 01/10/2017 
1 1 NaN 02/09/2017 
2 1 6.0 02/10/2016 
3 2 5.0 01/10/2017 
4 2 NaN 01/11/2017 
5 2 7.0 02/10/2016 

мне нужно группы по столбцу «а», и заполнить NaN со значением столбца «B», где дата для этой строки ближе всего к дате в строке NaN ,

Так вывод должен выглядеть следующим образом:

a b  date 
0 1 4.0 01/10/2017 
1 1 6.0 02/09/2017 
2 1 6.0 02/10/2016 
3 2 5.0 01/10/2017 
4 2 5.0 01/11/2017 
5 2 7.0 02/10/2016 

Предположим, что существует функция closest_date(), который принимает дату NaN и список других дат в этой группе, и возвращает ближайшую дату.

Я пытаюсь найти чистое решение, которое не требует итерации по строкам, идеально подходящее для использования apply() с lambdas. Есть идеи?

+0

Ваши данные, кажется неправильным. Для группы 'a == 1' вы выбрали' 6' для заполнения 'nan'. Однако, похоже, что '01/10/2017' ближе к' 02/09/2017', подразумевая, что '4' должно было быть значением заполнения. – piRSquared

ответ

0

Это должно работать:

df['closest_date_by_a'] = df.groupby('a')['date'].apply(closest_date) 
df['b'] = df.groupby(['a', 'closest_date_by_a'])['b'].ffill().bfill() 

Учитывая функцию (closest_date()), вам нужно применить эту функцию группы так вычисляет ближайшие даты для строк в каждой группе. Затем вы можете группировать как основной столбец группировки (a), так и ближайший столбец даты (closest_date_by_a) и выполнять заполнение.

0

Убедитесь, что столбец date - это даты.

df = pd.DataFrame(
    {'date': ['01/10/2017', '02/09/2017', '02/10/2016','01/10/2017', '01/11/2017', '02/10/2016'], 
    'a':[1,1,1,2,2,2], 'b':[4,np.nan,6, 5, np.nan, 7]}) 
df.date = pd.to_datetime(df.date) 

print(df) 

    a b  date 
0 1 4.0 2017-01-10 
1 1 NaN 2017-02-09 
2 1 6.0 2016-02-10 
3 2 5.0 2017-01-10 
4 2 NaN 2017-01-11 
5 2 7.0 2016-02-10 

reindex Использование с method='nearest' после dropna()

def fill_with_nearest(df): 
    s = df.set_index('date').b 
    s = s.dropna().reindex(s.index, method='nearest') 
    s.index = df.index 
    return s 

df.loc[df.b.isnull(), 'b'] = df.groupby('a').apply(fill_with_nearest).reset_index(0, drop=True) 

print(df) 

    a b  date 
0 1 4.0 2017-01-10 
1 1 4.0 2017-02-09 
2 1 6.0 2016-02-10 
3 2 5.0 2017-01-10 
4 2 5.0 2017-01-11 
5 2 7.0 2016-02-10 
+0

Спасибо за ответ. Я не знал о методе «ближайшего» заполнения, это довольно аккуратно. Я пытаюсь использовать этот метод для своих данных, и он работает для нескольких итераций, а затем дает ошибку: 'ValueError: не может переиндексировать неидеальный индекс с помощью метода или ограничения Есть ли идеи, что может вызвать это? Я попытался воссоздать ошибку на примере, добавив новые строки с одинаковыми значениями «дата», но все равно работает нормально. – yobogoya

 Смежные вопросы

  • Нет связанных вопросов^_^