Заменяйте строку в pandas следующей строкой только тогда, когда вся строка (каждый столбец) имеет значения NaN

#python #python-3.x #pandas

#python #python-3.x #pandas

Вопрос:

У меня есть фрейм данных, в котором я хочу заменить только строки со значениями NaN в каждом столбце на строку под ним. Я пробовал решения из нескольких каналов и использовал ffill, но это привело к заполнению нескольких ячеек, а не всей строки.

      ss       s        h       b     sb
0   NaN     NaN      NaN     NaN    NaN
1   3.0     NaN     14.0     NaN    8.0
2   9.0     8.0     23.0     NaN    2.0
3   NaN     NaN      NaN     NaN    NaN
4   NaN     NaN      NaN     NaN    NaN
5   1.0     6.0      7.0    11.0    3.0
 

Ожидаемый результат:

      ss       s        h       b     sb
0   3.0     NaN     14.0     NaN    8.0
1   3.0     NaN     14.0     NaN    8.0
2   9.0     8.0     23.0     NaN    2.0
3   1.0     6.0      7.0    11.0    3.0
4   1.0     6.0      7.0    11.0    3.0
5   1.0     6.0      7.0    11.0    3.0
 

Комментарии:

1. Если использовать df = df.bfill(limit=2) его, он не работает для s

Ответ №1:

Вы можете создавать группы, проверяя строки только с отсутствующими значениями с кумулятивной суммой по порядку изменения столбца и переходите к GroupBy.bfill :

 df = df.groupby((df.notna().any(axis=1)).iloc[::-1].cumsum().iloc[::-1]).bfill()

print (df)
    ss    s     h     b   sb
0  3.0  NaN  14.0   NaN  8.0
1  3.0  NaN  14.0   NaN  8.0
2  9.0  8.0  23.0   NaN  2.0
3  1.0  6.0   7.0  11.0  3.0
4  1.0  6.0   7.0  11.0  3.0
5  1.0  6.0   7.0  11.0  3.0
 

Подробнее:

 print ((df.notna().any(axis=1)).iloc[::-1].cumsum().iloc[::-1])
0    3
1    3
2    2
3    1
4    1
5    1
dtype: int32
 

Комментарии:

1. Итак, если я установлю ограничение в 5? Это не заменит s? Потому что я хочу заменить только в том случае, если все значения в строке равны NaN, на следующую строку. Даже если в следующей строке есть NaN, это нормально.

2. @YashGhorpade — Мой вопрос: limit = 2 работает для s , поэтому не уверен, почему в ожидаемом выходе есть NAN.

3. Для начала замены вся строка должна быть NaN. Затем вы заменяете строку ниже. Первая строка не заменяется, поскольку это не только NaNs. Затем нулевая строка имеет NaN, скопированный из первой строки.

4. Поскольку я хочу заменить пустую строку точно так же, как и другую строку, если в другой строке есть NaN, исходная строка также должна иметь тот же NaN.