2017-08-24 7 views
2

J'ai un dataframe comme ceci:Fractionnement dataframe par de multiples dimensions avec le dictionnaire 2D automatiquement nommé dataframes

 df = pd.DataFrame({ 
       'Client':['A','B','C','D','E'], 
       'Revenue':[100,120,50,40,30], 
       'FYoQ':['FY','Q','Q','Q','FY'], 
       'Quarter':[np.nan,1,3,4,np.nan], 
       'Year':[2017,2016,2015,2017,2016] 
     }) 

Comment puis-je diviser la trame de données pour obtenir un 2 dataframe dictionnaire dimensions
ds [année] [trimestre ] pour chaque année et chaque trimestre.

En ce moment, je suis capable de faire un dictionnaire 1 dimensions comme suit:

years=df['Year'].unique().tolist() 
    mc={elem:pd.DataFrame for elem in years} 

    for year in years: 
     mc[year]=df.loc[(df['Year']==year)] 

De cette façon, j'obtenir un dictionnaire de dataframe mc [2015], mc [2016], etc.
Et puis je à nouveau devoir appliquer la même chose à chacun d'eux.

J'espérais qu'il y aurait une modification du code:

mc={elem:pd.DataFrame for elem in years} 

pour créer un 2 dimensions (ou même dictionnaire multi-dimensionnelle) à la fois, ce qui permet la séparation des données plus rapides. Vous pouvez définir un multi-index en utilisant df.set_index, suivi d'un appel df.groupby

+0

Vous devriez envisager de marquer un de nos réponses comme acceptées si elles ont aidé. –

Répondre

2
from collections import defaultdict 

d = defaultdict(dict) 
[d[y].setdefault(q, g) for (y, q), g in df.groupby(['Year', 'Quarter'])]; 
d = dict(d) 

for y, v in d.items(): 
    print(y) 
    for q, s in v.items(): 
     print(' ' + str(q)) 
     p = s.__repr__() 
     p = '\n'.join(['  ' + l for l in p.split('\n')]) 
     print(p, '\n') 

2015 
    3.0 
      Client FYoQ Quarter Revenue Year 
     2  C Q  3.0  50 2015 

2016 
    1.0 
      Client FYoQ Quarter Revenue Year 
     1  B Q  1.0  120 2016 

2017 
    4.0 
      Client FYoQ Quarter Revenue Year 
     3  D Q  4.0  40 2017 
+0

Note d'utilisation (à OP): Un dictionnaire à un seul niveau facilite un accès plus rapide qu'un dictionnaire imbriqué nécessitant deux recherches séparées. –

+1

D'accord! Mais OP a demandé le 2-D. Je le vois comme, c'est ce que l'OP a demandé. Votre est ce dont OP a besoin. – piRSquared

+0

Totes homme juste. –

2

Ensuite, construire votre dictionnaire dans une compréhension dict:

dict_ = {i : g for i, g in df.set_index(['Year', 'Quarter']).groupby(level=[0, 1])} 

for k in dict_: 
    print(dict_[k]) 

      Client FYoQ Revenue 
Year Quarter      
2016 1.0   B Q  120 


      Client FYoQ Revenue 
Year Quarter      
2015 3.0   C Q  50 


      Client FYoQ Revenue 
Year Quarter      
2017 4.0   D Q  40 

Les touches sont (year, quarter) tuples, qui sont très facile à gérer.


Pour enregistrer dans un fichier CSV, la dernière boucle aura besoin d'un appel .to_csv:

for k in dict_: 
    label = 'data{}Q{}'.format(map(str, k)) 
    dict_[k].to_csv(label) 
+0

Merci, laissez-moi essayer cela. –

+0

Merci cela fonctionne. Je me demandais comment modifier la dernière boucle pour que je puisse écrire pd.to_csv les différents fichiers résultants avec les fichiers obtenant des noms automatiquement comme "data2015Q1.csv", "data2015Q2.csv", ...., "data2016Q4. csv "... –

+0

@AlhpaDelta Édité. Vous aurez besoin de '.to_csv'. –