Как сгруппировать по уровню 0 и описать в многоиндексном и уровневом фрейме данных (панды)?

Вот (файл) мультииндексный и уровневый фрейм данных. Загрузка фрейма данных из CSV:

import pandas as pd
df = pd.read_csv('./enviar/only-bh-extreme-events-satellite.csv'
                  ,index_col=[0,1,2,3,4]
                  ,header=[0,1,2,3]
                  ,skipinitialspace=True
                  ,tupleize_cols=True
                ) 

df.columns = pd.MultiIndex.from_tuples(df.columns)

print(df)

                                                         ci                 \
                                                          1                  
                                                          1                  
                                                        00h  06h  12h  18h   
wsid lat        lon        start               prcp_24                       
329  -43.969397 -19.883945 2007-03-18 10:00:00 72.0     NaN  NaN  NaN  NaN   
                           2007-03-20 10:00:00 104.4    NaN  NaN  NaN  NaN   
                           2007-10-18 23:00:00 92.8     NaN  NaN  NaN  NaN   
                           2007-12-21 00:00:00 60.4     NaN  NaN  NaN  NaN   
                           2008-01-19 18:00:00 53.0     NaN  NaN  NaN  NaN   
                           2008-04-05 01:00:00 80.8     0.0  0.0  0.0  0.0   
                           2008-10-31 17:00:00 101.8    NaN  NaN  NaN  NaN   
                           2008-11-01 04:00:00 82.0     NaN  NaN  NaN  NaN   
                           2008-12-29 00:00:00 57.8     NaN  NaN  NaN  NaN   
                           2009-03-28 10:00:00 72.4     NaN  NaN  NaN  NaN   
                           2009-10-07 02:00:00 57.8     NaN  NaN  NaN  NaN   
                           2009-10-08 00:00:00 83.8     NaN  NaN  NaN  NaN   
                           2009-11-28 16:00:00 84.4     NaN  NaN  NaN  NaN   
                           2009-12-18 04:00:00 51.8     NaN  NaN  NaN  NaN   
                           2009-12-28 00:00:00 96.4     NaN  NaN  NaN  NaN   
                           2010-01-06 05:00:00 74.2     NaN  NaN  NaN  NaN   
                           2011-12-18 00:00:00 113.6    NaN  NaN  NaN  NaN   
                           2011-12-19 00:00:00 90.6     NaN  NaN  NaN  NaN   
                           2012-11-15 07:00:00 85.8     NaN  NaN  NaN  NaN   
                           2013-10-17 00:00:00 52.4     NaN  NaN  NaN  NaN   
                           2014-04-01 22:00:00 72.0     0.0  0.0  0.0  0.0   
                           2014-10-20 06:00:00 56.6     NaN  NaN  NaN  NaN   
                           2014-12-13 09:00:00 104.4    NaN  NaN  NaN  NaN   
                           2015-02-09 00:00:00 62.0     NaN  NaN  NaN  NaN   
                           2015-02-16 19:00:00 56.8     NaN  NaN  NaN  NaN   
                           2015-05-06 17:00:00 50.8     0.0  0.0  0.0  0.0   
                           2016-02-26 00:00:00 52.2     NaN  NaN  NaN  NaN   
343  -44.416883 -19.885398 2008-08-30 21:00:00 50.4     0.0  0.0  0.0  0.0   
                           2009-02-01 01:00:00 53.8     NaN  NaN  NaN  NaN   
                           2010-03-22 00:00:00 51.4     NaN  NaN  NaN  NaN   
                           2011-11-12 21:00:00 57.8     NaN  NaN  NaN  NaN   
                           2011-11-25 22:00:00 107.6    NaN  NaN  NaN  NaN   
                           2012-12-28 20:00:00 94.0     NaN  NaN  NaN  NaN   
                           2013-10-16 22:00:00 50.8     NaN  NaN  NaN  NaN   
                           2014-11-06 21:00:00 55.2     NaN  NaN  NaN  NaN   
                           2015-01-24 00:00:00 80.0     NaN  NaN  NaN  NaN   
                           2015-01-27 00:00:00 52.8     NaN  NaN  NaN  NaN   
370  -43.958651 -19.980034 2015-01-28 23:00:00 50.4     NaN  NaN  NaN  NaN   
                           2015-01-29 00:00:00 50.6     NaN  NaN  NaN  NaN

Я пытаюсь описать группировку по уровню (0), переменным ci, d, r, z ... Мне нравится получать количество, максимальное, минимальное, стандартное и т. д.

Когда я попробовал df.describe (), я не получил группировку по уровню 0. Поэтому я ожидал:

    ci     cc     z     r -> Level 0
count   39.000000   39.000000   39.000000   39.000000
mean    422577.032051   422025.595353   421672.402244   422449.004808
std     144740.869473   144550.040108   144425.167173   144692.422425
min     0.000000    0.000000    0.000000    0.000000
25%     467962.437500   467512.156250   467915.437500   468552.750000
50%     470644.687500   469924.468750   469772.312500   470947.468750
75%     472557.875000   471953.828125   471156.250000   472279.937500
max     473988.062500   473269.187500   472358.125000   473675.812500
0
0
462
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я создал эту вспомогательную функцию:

def format_percentiles(percentiles):
    percentiles = np.asarray(percentiles)
    percentiles = 100 * percentiles
    int_idx = (percentiles.astype(int) == percentiles)
    if np.all(int_idx):
        out = percentiles.astype(int).astype(str)
        return [i + '%' for i in out]

И это моя собственная функция описания:

import numpy as np
from functools import reduce
def describe_customized(df):
    _df = pd.DataFrame()
    data = []
    variables = list(set(df.columns.get_level_values(0)))
    variables.sort()
    for var in variables:
        idx = pd.IndexSlice
        values = df.loc[:, idx[[var]]].values.tolist()  #get all values from a specif variable
        z = reduce(lambda x,y: x+y,values)  #flat a list of list
        data.append(pd.Series(z,name=var))
    #return data
    for series in data:
        percentiles = np.array([0.25, 0.5, 0.75])
        formatted_percentiles = format_percentiles(percentiles)
        stat_index = (['count', 'mean', 'std', 'min'] + formatted_percentiles + ['max'])
        d = ([series.count(), series.mean(), series.std(), series.min()] +
             [series.quantile(x) for x in percentiles] + [series.max()])
        s = pd.Series(d, index=stat_index, name=series.name)
        _df = pd.concat([_df,s], axis=1)
    return _df

dd = describe_customized(df)

Результат:

               al         asn            cc        chnk    ci          ciwc  \
25%      0.130846    0.849998      0.000000    0.018000   0.0  0.000000e+00   
50%      0.131369    0.849999      0.000000    0.018000   0.0  0.000000e+00   
75%      0.134000    0.849999      0.000000    0.018000   0.0  0.000000e+00   
count  624.000000  624.000000  23088.000000  624.000000  64.0  2.308800e+04   
max      0.137495    0.849999      1.000000    0.018006   0.0  5.576574e-04   
mean     0.119082    0.762819      0.022013    0.016154   0.0  8.247306e-07   
min      0.000000    0.000000      0.000000    0.000000   0.0  0.000000e+00   
std      0.040338    0.258087      0.098553    0.005465   0.0  8.969210e-06  

Я создал функцию, которая возвращает новый фрейм данных со статистикой переменных для выбранного вами уровня:

def describe_levels(df,level):

    df_des = pd.DataFrame(
                            index=df.columns.levels[0],
                            columns=['count','mean','std','min','25','50','75','max']
                         )
    for index in df_des.index:

        df_des.loc[index,'count'] = len(df[index]['1'][level])
        df_des.loc[index,'mean']  = df[index]['1'][level].mean().mean()
        df_des.loc[index,'std']   = df[index]['1'][level].std().mean()
        df_des.loc[index,'min']   = df[index]['1'][level].min().mean()
        df_des.loc[index,'max']   = df[index]['1'][level].max().mean()
        df_des.loc[index,'25']    = df[index]['1'][level].quantile(q=0.25).mean()
        df_des.loc[index,'50']    = df[index]['1'][level].quantile(q=0.5).mean()
        df_des.loc[index,'75']    = df[index]['1'][level].quantile(q=0.75).mean()

    return df_des

Например, я позвонил:

describe_levels(df,'1').T

См. Здесь результат для уровня давления 1:

enter image description here

Спасибо, Леандро, но ваш код описывает каждый уровень давления отдельно. В моем случае для некоторых переменных у меня было 37 уровней давления, поэтому мне придется описывать как минимум 37 раз. Мои основные цели - просто рассматривать каждую переменную как единожды, описывая сгруппированные все уровни давления. Так, например, для переменной r (относительная влажность) на 37 уровнях * 4 дня * 4 раза в день (00ч, 06ч, 12ч, 18ч) = 592, поскольку у меня есть 39 записей (экземпляров), счетчик для переменной r должен быть 592 * 39 = 23088.

Andre Araujo 03.11.2018 15:01

Другие вопросы по теме