J'ai le dataframe suivant:

df=pd.DataFrame(np.array([[1,2,3,4,7,9,5],[2,6,5,4,9,8,2],[3,5,3,21,12,6,7],[1,7,8,4,3,4,3]]),
              columns=['9:00:00','9:05:00','09:10:00','09:15:00','09:20:00','09:25:00','09:30:00'])


>>> 9:00:00     9:05:00       09:10:00  09:15:00    09:20:00    09:25:00    09:30:00 ....
a       1          2             3         4           7           9           5
b       2          6             5         4           9           8           2
c       3          5             3         21         12           6           7
d       1          7             8         4           3           4           3

Je voudrais obtenir pour chaque ligne (par exemple a,b,c,d ...) la valeur moyenne entre des heures spécifiques. Les heures sont comprises entre 9 et 15 et je souhaite regrouper par période, par exemple pour calculer la valeur moyenne entre 09:00:00 et 11:00:00, entre 11-12, entre 13-15 (ou toute période que je décide à). J'essaie d'abord de convertir les valeurs des colonnes au format datetime, puis j'ai pensé qu'il serait plus facile de le faire :

df.columns = pd.to_datetime(df.columns,format="%H:%M:%S")

Mais alors j'ai eu les noms de coolumns avec une fausse année "1900-01-01 09:00:00" ... Et aussi, les en-têtes de colonnes ont été objet, alors je me sentais un peu perdu ...

Mon objectif final est de pouvoir calculer de nouvelles colonnes avec la valeur moyenne pour chaque ligne uniquement entre les colonnes comprises dans la période définie (par exemple, 9-11, etc...)

1
Reut 24 mars 2021 à 15:48

2 réponses

Meilleure réponse

Si besoin d'une certaine période, par ex. toutes les 2 heures :

df.columns = pd.to_datetime(df.columns,format="%H:%M:%S")

df1 = df.resample('2H', axis=1).mean()
print (df1)
   1900-01-01 08:00:00
0             4.428571
1             5.142857
2             8.142857
3             4.285714

Si nécessaire des périodes personnalisées est possible, utilisez {{x0} }:

df.columns = pd.to_datetime(df.columns,format="%H:%M:%S")

bins = ['5:00:00','9:00:00','11:00:00','12:00:00', '23:59:59']
dates = pd.to_datetime(bins,format="%H:%M:%S")
labels = [f'{i}-{j}' for i, j in zip(bins[:-1], bins[1:])] 
df.columns = pd.cut(df.columns, bins=dates, labels=labels, right=False)
print (df)
   9:00:00-11:00:00  9:00:00-11:00:00  9:00:00-11:00:00  9:00:00-11:00:00  \
0                 1                 2                 3                 4   
1                 2                 6                 5                 4   
2                 3                 5                 3                21   
3                 1                 7                 8                 4   

   9:00:00-11:00:00  9:00:00-11:00:00  9:00:00-11:00:00  
0                 7                 9                 5  
1                 9                 8                 2  
2                12                 6                 7  
3                 3                 4                 3  

Et la dernière utilisation mean par colonnes, la raison des colonnes NaNs est que les colonnes sont catégoriques :

df2 = df.mean(level=0, axis=1)
print (df2)
   9:00:00-11:00:00  5:00:00-9:00:00  11:00:00-12:00:00  12:00:00-23:59:59
0          4.428571              NaN                NaN                NaN
1          5.142857              NaN                NaN                NaN
2          8.142857              NaN                NaN                NaN
3          4.285714              NaN                NaN                NaN

Pour éviter les colonnes NaN S, convertissez les noms de colonnes aux chaînes:

df3 = df.rename(columns=str).mean(level=0, axis=1)
print (df3)
   9:00:00-11:00:00
0          4.428571
1          5.142857
2          8.142857
3          4.285714

EDIT : Solution ci-dessus avec timedeltas, car format HH:MM:SS :

df.columns = pd.to_timedelta(df.columns)
print (df)
   0 days 09:00:00  0 days 09:05:00  0 days 09:10:00  0 days 09:15:00  \
0                1                2                3                4   
1                2                6                5                4   
2                3                5                3               21   
3                1                7                8                4   

   0 days 09:20:00  0 days 09:25:00  0 days 09:30:00  
0                7                9                5  
1                9                8                2  
2               12                6                7  
3                3                4                3 

bins = ['9:00:00','11:00:00','12:00:00']
dates = pd.to_timedelta(bins)
labels = [f'{i}-{j}' for i, j in zip(bins[:-1], bins[1:])] 
df.columns = pd.cut(df.columns, bins=dates, labels=labels, right=False)
print (df)
   9:00:00-11:00:00  9:00:00-11:00:00  9:00:00-11:00:00  9:00:00-11:00:00  \
0                 1                 2                 3                 4   
1                 2                 6                 5                 4   
2                 3                 5                 3                21   
3                 1                 7                 8                 4   

   9:00:00-11:00:00  9:00:00-11:00:00  9:00:00-11:00:00  
0                 7                 9                 5  
1                 9                 8                 2  
2                12                 6                 7  
3                 3                 4                 3 

#missing values because not exist datetimes between 11:00:00-12:00:00
df2 = df.mean(level=0, axis=1)
print (df2)
   9:00:00-11:00:00  11:00:00-12:00:00
0          4.428571                NaN
1          5.142857                NaN
2          8.142857                NaN
3          4.285714                NaN

df3 = df.rename(columns=str).mean(level=0, axis=1)
print (df3)
   9:00:00-11:00:00
0          4.428571
1          5.142857
2          8.142857
3          4.285714
1
jezrael 24 mars 2021 à 14:08

Je vais vous montrer mon code et les résultats après l'éjection.

Premières bibliothèques d'importation et Dataframe

import numpy as np
import pandas as pd

df=pd.DataFrame(np.array([[1,2,3,4,7,9,5],[2,6,5,4,9,8,2],[3,5,3,21,12,6,7], 
[1,7,8,4,3,4,3]]),
          columns= 
         ['9:00:00','9:05:00','09:10:00','09:15:00','09:20:00','09:25:00','09:30:00'])

Ce serait bien de créer une classe afin de définir ce qu'est une période :

class Period():
    def __init__(self,initial,end):
        self.initial=initial
        self.end=end

    def __repr__(self):
        return self.initial +' -- ' +self.end

Avec commande .Loc, nous pouvons obtenir un sous-dataframe avec les colonnes que je désire:

       `def get_colMean(df,period):
           df2 = df.loc[:,period.initial:period.end]
           array_mean = df.mean(axis=1).values

           col_name = 'mean_'+period.initial+'--'+period.end
           pd_colMean = pd.DataFrame(array_mean,columns=[col_name])

           return pd_colMean`        

Enfin, nous utilisons .join afin d'ajouter notre colonne avec les moyens à notre dataframe d'origine :

def join_colMean(df,period):
    pd_colMean = get_colMean(df,period)
    df = df.join(pd_colMean)
    return df

Je vais vous montrer mes résultats: Entrez la description de l'image ici

0
danihelovij 24 mars 2021 à 13:48