Pandas df.resample (): укажите порог NaN для расчета среднего

Я хочу передискретизировать кадр данных pandas с почасовой на годовую/ежедневную частоту с помощью метода how=mean. Однако, конечно, некоторые почасовые данные отсутствуют в течение года.

Как я могу установить порог для отношения разрешенных NaN до того, как среднее значение также будет установлено в NaN? Я не мог найти ничего, учитывая это в документах...

Заранее спасибо!


person user3017048    schedule 13.09.2015    source источник
comment
не понятно что вы хотите получить, выложите образец из ваших данных и ожидаемый результат   -  person Nader Hisham    schedule 13.09.2015


Ответы (2)


Вот простое решение с использованием groupby.

# Test data
start_date = pd.to_datetime('2015-01-01')
pd.date_range(start=start_date, periods=365*24, freq='H')
number = 365*24
df = pd.DataFrame(np.random.randint(1,10, number),index=pd.date_range(start=start_date, periods=number, freq='H'), columns=['values'])
# Generating some NaN to simulate less values on the first day
na_range = pd.date_range(start=start_date, end=start_date +  3 * Hour(), freq='H')
df.loc[na_range,'values'] = np.NaN

# grouping by day, computing the mean and the count
df = df.groupby(df.index.date).agg(['mean', 'count'])
df.columns = df.columns.droplevel()

# Populating the mean only if the number of values (count) is > to the threshold
df['values'] = np.NaN
df.loc[df['count']>=20, 'values'] = df['mean']
print(df.head)

# Result
                mean  count  values
2015-01-01  4.947368     20     NaN
2015-01-02  5.125000     24   5.125
2015-01-03  4.875000     24   4.875
2015-01-04  5.750000     24   5.750
2015-01-05  4.875000     24   4.875
person Romain    schedule 13.09.2015
comment
Хорошо, спасибо! Было бы неплохо, если бы это было интегрировано в саму функцию ресемпла.... - person user3017048; 14.09.2015

Вот альтернативное решение, основанное на передискретизации.

    # Test data (taken from Romain) 
    start_date = pd.to_datetime('2015-01-01')
    pd.date_range(start=start_date, periods=365*24, freq='H')
    number = 365*24
    df = pd.DataFrame(np.random.randint(1,10,    number),index=pd.date_range(start=start_date, periods=number, freq='H'), columns=['values'])
    # Generating some NaN to simulate less values on the first day
    na_range = pd.date_range(start=start_date, end='2015-01-01 12:00', freq='H')
    df.loc[na_range,'values'] = np.NaN


    # Add a column with 1 if data is not NaN, 0 if data is NaN
    df['data coverage'] = (~np.isnan(df['values'])).astype(int)
    df = df.resample('D').mean()
    # Specify a threshold on data coverage of 80% 
    threshold = 0.8
    df.loc[df['data coverage'] < threshold, 'values'] = np.NaN
    print(df.head)

    # Result
          values  data coverage
    2015-01-01       NaN       0.458333
    2015-01-02  5.708333       1.000000
    2015-01-03  5.083333       1.000000
    2015-01-04  4.958333       1.000000
    2015-01-05  5.125000       1.000000
    2015-01-06  4.791667       1.000000
    2015-01-07  5.625000       1.000000
person Basileios    schedule 17.07.2018