Создание мультииндекса (3 оси) для получения среднего значения по 1 оси

#python #pandas

#python #pandas

Вопрос:

У меня есть список фреймов данных, который состоит из временных рядов с индексом datetime. У меня есть другой список с именем longname, который я хочу связать с каждым из этих фреймов данных. Я хотел бы сгруппировать эти фреймы данных-longname со списком Mainlabel (который связан через длинное имя с помощью , MainName, SubName). Теперь я хочу получить среднее значение относительно индекса datetime из фрейма данных через longname и MainNames. Извините, если это звучит запутанно.

То, что я имею в виду, сбивает с толку и усложняет. Итак, мне было интересно, есть ли у кого-нибудь лучший подход, который я должен использовать. Что я сделал до сих пор, так это расширил список фреймов данных в 1 столбец с помощью pd.concat(), но, похоже, не могу пометить их, используя аргумент «keys» для longname, что выдает ошибку ValueError: Shape of passed values is (823748, 2), indices imply (3343070, 2) . это приводит к потере моего второго индексатора. Что, если бы это сработало, я надеялся просто сгруппировать их, используя shortname .например.

 ShortNames = ['MainName1','MainName2']

idx = allvars.index.str.extract('('  '|'.join(ShortNames)   ')', expand=False)

Allmean = allvars.groupby(idx).mean(axis = (1,2,3))
  

У меня есть несколько фреймов данных, которые выглядят так же, как этот;

             Amount(mm)
Date                  
1900-01-01         0.0
1900-01-02         0.0
1900-01-03         5.1
1900-01-04         0.0
1900-01-05         0.0
1900-01-06         0.0
1900-01-07         0.0
  

список длинных имен, который у меня есть, выглядит так:

 longnames = ['MainName1,SubName1', 'MainName1,SubName2', 'MainName2,SubName1', 'MainName2,SubName2']
  

В целом я хочу использовать среднее значение исключительно для индекса datetime, но оно сгруппировано по основным именам. Таким образом, это должно привести к получению только 2 индексов. Который является индексом MainName и DateTime. Аналогично;

                                Amount(mm)
                   Date                  
MainName1          1900-01-01         0.0
                   1900-01-02         0.0
                   1900-01-03         5.1
                   1900-01-04         0.0
                   1900-01-05         0.0
                   1900-01-06         0.0
                   1900-01-07         0.0
MainName2          1900-01-04         8.0
                   1900-01-05         9.0
                   1900-01-06         1.0
                   1900-01-07         2.0
  

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

1. Для чего нужен ваш код concat ?

2. pd.concat(dfs, keys = longsnames) где dfs — это список фреймов данных

3. что такое print (len(dfs)) ?

4. 113….фреймы данных

Ответ №1:

Пример DataFrames :

 print (df1)
print (df2)
print (df3)
            Amount(mm)
Date                  
1900-01-01         0.0
1900-01-02         0.0
1900-01-03         5.1
1900-01-04         0.0
1900-01-05         0.0
1900-01-06         0.0
1900-01-07         0.0
            Amount(mm)
Date                  
1900-01-01         4.0
1900-01-02         5.0
1900-01-03         5.1
1900-01-04         6.0
            Amount(mm)
Date                  
1900-01-04         8.0
1900-01-05         9.0
1900-01-06         1.0
1900-01-07         2.0
  

Сначала необходим список одинаковой длины longsnames с числом DataFrames (здесь 3)

 dfs = [df1,df2,df3]
longsnames = ['MainName1,SubName1', 'MainName1,SubName2', 'MainName2,SubName1']

allvars = pd.concat(dfs, keys = longsnames)
print (allvars)
                               Amount(mm)
                   Date                  
MainName1,SubName1 1900-01-01         0.0
                   1900-01-02         0.0
                   1900-01-03         5.1
                   1900-01-04         0.0
                   1900-01-05         0.0
                   1900-01-06         0.0
                   1900-01-07         0.0
MainName1,SubName2 1900-01-01         4.0
                   1900-01-02         5.0
                   1900-01-03         5.1
                   1900-01-04         6.0
MainName2,SubName1 1900-01-04         8.0
                   1900-01-05         9.0
                   1900-01-06         1.0
                   1900-01-07         2.0
  

затем необходимо выбрать первый уровень MultiIndex по Index.get_level_values :

 ShortNames = ['MainName1','MainName2']

idx = allvars.index.get_level_values(0).str.extract('('  '|'.join(ShortNames)   ')', expand=False)
print (idx)
Index(['MainName1', 'MainName1', 'MainName1', 'MainName1', 'MainName1',
       'MainName1', 'MainName1', 'MainName1', 'MainName1', 'MainName1',
       'MainName1', 'MainName2', 'MainName2', 'MainName2', 'MainName2'],
      dtype='object')
  

И последний агрегат mean :

 Allmean = allvars.groupby([idx, 'Date']).mean()
#oldier pandas version alternative
#Allmean = allvars.groupby([idx, allvars.index.get_level_values(1)]).mean()
print (Allmean)
                      Amount(mm)
          Date                  
MainName1 1900-01-01         0.0
          1900-01-02         0.0
          1900-01-03         5.1
          1900-01-04         0.0
          1900-01-05         0.0
          1900-01-06         0.0
          1900-01-07         0.0
MainName2 1900-01-01         4.0
          1900-01-02         5.0
          1900-01-03         5.1
          1900-01-04         6.0
  

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

1. Это не тот результат, который я искал, но спасибо, что нашли время. Я надеялся просто получить среднее значение для каждого дня каждого основного имени. Таким образом, результат должен по-прежнему содержать индекс даты и времени, а также индекс MainName. Но чтобы исправить это, не могли бы мы просто изменить get_level_values(0) термин на get_level_values(1) ?. Я обновлю свой пост, чтобы увидеть, какими должны быть результаты. Также побочная тема; длина моих длинных имен и фреймов данных одинакова, и это по-прежнему выдает мне ту же ошибку.

2. Ваши ответы такие быстрые! Я действительно ценю это! Я переделал ваш код, и кажется, что мои данные могут быть неисправны, поэтому он выдавал мне ошибку, но я принимаю ваш ответ сейчас! Еще раз спасибо!