подсчитывать значения каждого месяца, заполнять NaN, если при определенном пределе

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

Я работаю с фреймом данных, где каждый столбец представляет компанию. Индекс является datetime индексом с ежедневной частотой. Моя проблема заключается в следующем: для каждой компании я хотел бы заполнить месяц NaN , если в этом месяце меньше 20 значений. В приведенном ниже примере это будет означать, что Company_1 запись 0.91 для 2012-08-31 будет изменена на NaN , в то время как company_2 и 3 будут неизменными.

                Company_1      Company_2   Company_3
2012-08-01     NaN            0.99        0.11
2012-08-02     NaN            0.21        NaN
2012-08-03     NaN            0.32        0.40
...            ...            ...         ...
2012-08-29     NaN            0.50       -0.36
2012-08-30     NaN            0.48       -0.32
2012-08-31     0.91           0.51       -0.33

Total Values:  1                22          21
  

Я изо всех сил пытаюсь найти эффективный способ подсчета количества значений для каждого месяца каждого запаса. Теоретически я мог бы написать функцию, которая создает новый фрейм данных, который сообщает количество значений за каждый месяц (и для каждой акции), чтобы затем использовать этот фрейм данных для исходной информации о компании, но я уверен, что должен быть более простой способ. Любая помощь высоко ценится. Заранее спасибо.

Ответ №1:

groupby фрейм данных с ежемесячной частотой и transform используя count затем с помощью Series.lt создайте логическую маску и используйте эту маску для заполнения NaN значений в фрейме данных:

 df1 = df.mask(df.groupby(pd.Grouper(freq='M')).transform('count').lt(20))
  

 print(df1)
            Company_1  Company_2  Company_3
2012-08-01        NaN       0.99       0.11
2012-08-02        NaN       0.21        NaN
2012-08-03        NaN       0.32       0.40
....
2012-08-29        NaN       0.50      -0.36
2012-08-30        NaN       0.48      -0.32
2012-08-31        NaN       0.51      -0.33
  

Ответ №2:

IIUC:

 df.loc[:, df.apply(lambda d: d.notnull().sum()<20)] = np.NaN

print (df)

            Company 1  Company 2  Company 3
2012-08-01        NaN       0.99       0.11
2012-08-02        NaN       0.21        NaN
2012-08-03        NaN       0.32       0.40
2012-08-29        NaN       0.50      -0.36
2012-08-30        NaN       0.48      -0.32
2012-08-31        NaN       0.51      -0.33