Количество последовательных нулей, сгруппированных по ключевому столбцу в фрейме данных Pandas

#python #pandas #dataframe #pandas-groupby

Вопрос:

Мой набор данных(годовые данные) выглядит следующим образом

 CODE        Date        PRCP    TAVG        TMAX        TMIN
AE000041196 01-01-2020  0       21.1        
AE000041196 02-01-2020  0       21.4        
AE000041196 03-01-2020  0       21.2                    15.4
AE000041196 04-01-2020  0       21.9                    14.9
AE000041196 05-01-2020  0       23.7                    16.5
AE000041196 06-01-2020  0.5     20.7        
AE000041196 07-01-2020  0       18.1                    11.5
AE000041196 08-01-2020  0       19.6                    10.3
AE000041196 09-01-2020  0.3     20.6                    13.8
 

Я пытаюсь выяснить наибольшее количество последовательных пропущенных значений[Максимальное количество последовательных NaN для каждого 'CODE' ] для столбцов TMAX и TMIN для каждого значения в КОДЕ. например. Из ограниченного набора данных выше:
Максимальное последовательное пропущенное значение для TMAX будет равно 9, а для TMIN будет равно 2

Код, который я использую

 df['TMAX_nullccount'] = df.TMAX.isnull().astype(int).groupby(df['TMAX'].notnull().astype(int).cumsum()).cumsum()
 

Это приводит к ошибкам в наборе данных, когда

 CODE        Date        PRCP  TAVG  TMAX TMIN   TMAX_nullccount
CA1AB000014 10-03-2021  2.3                     297
CA1AB000014 11-03-2021  0                       298
CA1AB000014 12-03-2021  0                       299
CA1AB000014 13-03-2021  0                       300
CA1AB000014 14-03-2021  0                       301
CA1AB000015 01-01-2021  0                       302
CA1AB000015 02-01-2021  0                       303
CA1AB000015 03-01-2021  0                       304
CA1AB000015 04-01-2021  0                       305
 

Теоретически счетчик(TMAX_nullcount) должен был снова начинаться с 0. Код был изменен с CA1AB000014 на CA1AB000015 . Также значение в столбце TMAX_nullcount не может превышать 365(годовой набор данных), но мой код дает значения намного больше.

Ожидаемый выходной файл(значения составлены)

 CODE            TMAX_maxcnullcount  TMIN_maxcnullcount  TAVG_maxcnullcount
AE000041196             2               2                       0
AEM00041194             1               1                       0
AEM00041217             3               1                       0
AEM00041218             1               2                       45
AFM00040938             65              65                      0
AFM00040948             132             132                     0
AG000060390             155             141                     0
 

Как я могу это исправить? Заранее спасибо

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

1. Отсутствуют значения np. НэН или '' . Кроме того, ваша группа не рассматривает CODE

2. @JoeFerndz Они являются np.NaNs.

3. Я дал вам самый длинный и самый короткий последовательный нулевой результат. Не стесняйтесь изменять код. На самом деле я неправильно понял ваш вопрос.

4. @Pygirl Я не могу приписать нули с 0 в моем наборе данных, потому что 0 также является наблюдением, и существует вероятность того, что это вменение может исказить результат. Когда я запустил ваш код, он вернул постоянное значение(73) для всех строк. Как упоминалось в вопросе, я хочу, чтобы последовательное количество нулей(NaNs)

Ответ №1:

Вы можете использовать:

Сначала проверьте, соответствуют ли отсутствующие значения:

 print (df.isna())
    CODE   Date   PRCP   TAVG  TMAX   TMIN
0  False  False  False  False  True   True
1  False  False  False  False  True   True
2  False  False  False  False  True  False
3  False  False  False  False  True  False
4  False  False  False  False  True  False
5  False  False  False  False  True   True
6  False  False  False  False  True  False
7  False  False  False  False  True  False
8  False  False  False  False  True  False
 

 #columsn for test missing values 
cols = ['TMAX','TMIN','TAVG']
#CODe to index, filter columns and create one Series
m = df.set_index('CODE')[cols].isna().unstack()

#create consecutive groups and count them with maximal count per column and group
df = (m.ne(m.shift()).cumsum()
       .where(m)
       .groupby(level=[0,1]).value_counts()
       .max(level=[0,1])
       .unstack(0)
       .add_suffix('_maxcnullcount'))
print (df)
             TMAX_maxcnullcount  TMIN_maxcnullcount
CODE                                               
AE000041196                   9                   2
 

Ответ №2:

Вы можете попробовать что-то вроде этого:

 df.groupby(['CODE', df['PRCP'].ne(df['PRCP'].shift()).cumsum()]).size().max()
 

groupby по CODE и последовательным нулям затем вычисляется размер.

Ваш результат groupby (aggr->размер) будет:

 CODE         PRCP
AE000041196  1       5
             2       1
             3       2
             4       1
 

Теперь вы можете найти макс и мин.

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

 df1 = df.fillna(0)
df1.groupby(['CODE', df1['TMAX'].ne(df1['TMAX'].shift()).cumsum()]).size().max()
 

 9