DataFrameGroupBy diff () при условии

Предположим, что у меня есть DataFrame:

df = pd.DataFrame({'CATEGORY':['a','b','c','b','b','a','b'], 'VALUE':[pd.np.NaN,1,0,0,5,0,4]}) 

который выглядит

  CATEGORY VALUE 0 a NaN 1 b 1 2 c 0 3 b 0 4 b 5 5 a 0 6 b 4 

Я группирую его:

 df = df.groupby(by='CATEGORY') 

А теперь позвольте мне показать, что я хочу с помощью примера в одной группе «b»:

 df.get_group('b') 

группа b:

  CATEGORY VALUE 1 b 1 3 b 0 4 b 5 6 b 4 

Мне нужно : В рамках каждой группы подсчитывайте diff () между значениями VALUE , пропуская все NaN s и 0 s. Таким образом, результат должен быть:

  CATEGORY VALUE DIFF 1 b 1 - 3 b 0 - 4 b 5 4 6 b 4 -1 

Вы можете использовать diff для вычитания значений после сброса значений 0 и NaN :

 df = pd.DataFrame({'CATEGORY':['a','b','c','b','b','a','b'], 'VALUE':[pd.np.NaN,1,0,0,5,0,4]}) grouped = df.groupby("CATEGORY") # define diff func diff = lambda x: x["VALUE"].replace(0, np.NaN).dropna().diff() df["DIFF"] = grouped.apply(diff).reset_index(0, drop=True) print(df) CATEGORY VALUE DIFF 0 a NaN NaN 1 b 1.0 NaN 2 c 0.0 NaN 3 b 0.0 NaN 4 b 5.0 4.0 5 a 0.0 NaN 6 b 4.0 -1.0 

Звучит как работа для операции pd.Series.shift() вместе с маской notnull .

Сначала мы удаляем ненужные значения, прежде чем группировать данные

 nonull_df = df[(df['VALUE'] != 0) & df['VALUE'].notnull()] groups = nonull_df.groupby(by='CATEGORY') 

Теперь мы можем перемещаться внутри групп и вычислять diff

 nonull_df['next_value'] = groups['VALUE'].shift(1) nonull_df['diff'] = nonull_df['VALUE'] - nonull_df['next_value'] 

Наконец, и, возможно, вы можете скопировать данные обратно в исходный фрейм данных

 df.loc[nonull_df.index] = nonull_df df CATEGORY VALUE next_value diff 0 a NaN NaN NaN 1 b 1.0 NaN NaN 2 c 0.0 NaN NaN 3 b 0.0 1.0 -1.0 4 b 5.0 1.0 4.0 5 a 0.0 NaN NaN 6 b 4.0 5.0 -1.0