groupby с несколькими стратегиями заполнения одновременно (pandas) - PullRequest
1 голос
/ 20 июня 2020

Как можно сгруппировать по одному столбцу, а затем внутри каждой группы применить сразу несколько стратегий заполнения к другим столбцам? Множественное значение:

  1. если первый в группе, заменить на ноль, затем заполнить, пока не будет достигнута первая точка данных
  2. завершающие NaN заполнены
  3. для всех NaN между точками данных, bfill
  4. , если все-NaN, оставьте группу в покое

В основном у меня есть следующий фрейм данных:

    A    B     C
0   A  NaN   NaN
1   A  NaN   NaN
2   A  1.0  10.0
3   A  NaN   NaN
4   B  NaN   NaN
5   B  2.0  20.0
6   B  NaN  20.0
7   B  NaN   NaN
8   C  NaN   NaN
9   C  NaN   NaN
10  C  NaN   NaN
11  C  NaN  30.0

И я бы хотел, чтобы превратиться в:

    A    B     C
0   A    0     0
1   A    0     0
2   A  1.0  10.0
3   A  1.0  10.0
4   B    0     0
5   B  2.0  20.0
6   B  2.0  20.0
7   B  2.0  20.0
8   C  NaN     0
9   C  NaN     0
10  C  NaN     0
11  C  NaN  30.0

Я попытался получить первый элемент с помощью df.groupby('A').nth(1) и продолжить условно, но новый индекс, созданный groupby, не является исходным (т.е. 0,4,8 ), независимо от того, передаю ли я опцию .reset_index() или нет.

Код для воссоздания фрейма данных:


df = pd.DataFrame({'A' : ["A", "A", "A", "A",
                          "B", "B", "B", "B","C", "C", "C", "C"],
                   'B' : [np.nan, np.nan, 1, np.nan,
                          np.nan, 2, np.nan, np.nan,
                          np.nan, np.nan, np.nan, np.nan],
                   'C' : [np.nan, np.nan, 10, np.nan,
                          np.nan, 20, 20, np.nan,
                          np.nan, np.nan, np.nan, 30]})

1 Ответ

1 голос
/ 20 июня 2020

Одна из возможных идей - использовать DataFrame.groupby на A, а затем использовать настраиваемую функцию преобразователя:

def fx(s):
    if s.isna().all():
        return s
    elif pd.isna(s.iloc[0]):
        s.iloc[0] = 0
        s = s.ffill().bfill()
    return s

df[['B', 'C']] = df.groupby('A')[['B', 'C']].transform(fx)
# print(df)
    A    B     C
0   A  0.0   0.0
1   A  0.0   0.0
2   A  1.0  10.0
3   A  1.0  10.0
4   B  0.0   0.0
5   B  2.0  20.0
6   B  2.0  20.0
7   B  2.0  20.0
8   C  NaN   0.0
9   C  NaN   0.0
10  C  NaN   0.0
11  C  NaN  30.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...