2016-08-01 7 views
1

Ich habe 3 Ebenen der Gruppierung basierend auf 3 Tasten kombiniert: Tasten 1, 2, key3 Ich will bekommen die Summe einer Spalte (c1) für die folgende Kombination:Pandas Schlüssel, wenn die Gruppierung von mehreren Spalte

key1, sum(c1) 
key1, key2, sum(c1) 
key1, key2, key3, sum(c1) 

Ich bekomme die Summen in 3 verschiedenen dfs. (Sum_k1, sum_k1k2, sum_k1k2k3) ich den Datenrahmen zu kombinieren und darauf wandelt es in JSon wie folgt:

{ 
key1: { 
      sum: x1, 
      key2: { 
        sum: x2, 
        key3: { 
          sum: x3 
         } 
       } 
     } 
} 

Wie kann ich über diese gehen?

Antwort

1

Ich weiß nicht, ob dies der effizienteste Weg, um darüber zu gehen, aber das ist, was ich mit

import pandas as pd 
import random 

# Prepare the sample dataset 

table = [] 
for i in range(100000): 
    row = {'key1': random.choice('ABC'), 
      'key2': random.choice('KLM'), 
      'key3': random.choice('XYZ'), 
      'val' : random.randint(0,500)} 
    table.append(row) 

df = pd.DataFrame(table) 

# Aggregate the first level 

dict_agg = (df.groupby('key1') 
      .sum() 
      .rename(columns={'val':'sum'}) 
      .to_dict('index')) 

# Convert from numpy.int64 to Python scalar 
for idx, value in dict_agg.items(): 
    dict_agg[idx]['sum'] = int(dict_agg[idx]['sum']) 

# Aggregate the second level 

df_lvl2 = (df.groupby(['key1','key2']) 
      .sum() 
      .rename(columns={'val':'sum'}) 
      .to_dict('index')) 

# Assign the second level aggregation 

for idx, value in df_lvl2.items(): 
    dict_agg[idx[0]][idx[1]] = {'sum': int(value['sum'])} 

# Aggregate the final level 

df_lvl3 = (df.groupby(['key1','key2','key3']) 
      .sum() 
      .rename(columns={'val':'sum'}) 
      .to_dict('index')) 

# Assign the third level aggregation 

for idx, value in df_lvl3.items(): 
    dict_agg[idx[0]][idx[1]][idx[2]] = {'sum': int(value['sum'])} 

kam Das Endergebnis wird wie folgt aussehen:

{'A': {'K': {'X': {'sum': 929178}, 
    'Y': {'sum': 940925}, 
    'Z': {'sum': 938008}, 
    'sum': 2808111}, 
    'L': {'X': {'sum': 902581}, 
    'Y': {'sum': 953821}, 
    'Z': {'sum': 942942}, 
    'sum': 2799344}, 
    'M': {'X': {'sum': 930117}, 
    'Y': {'sum': 929257}, 
    'Z': {'sum': 910905}, 
    'sum': 2770279}, 
    'sum': 8377734}, 
'B': {'K': {'X': {'sum': 888818}, 
… 

Da dies ein dict ist, müssen Sie es json konvertieren, indem Sie:

import json 
output = json.dumps(dict_agg) 
+0

Weil ich mehrere Spalten zu summieren habe. Im Summenteil mache ich das. Für die 1. Ebene: 'df.groupby ('key1') ['col1']. Sum()'. to_dict ('index') schlägt fehl. – bashhike

+0

. Das Umbenennungsbit schlägt fehl. Das 'to_dict ('index') 'schlägt ebenfalls fehl. '.to_dict()' funktioniert jedoch. – bashhike

+0

Danke, obwohl. Das hilft. Ich kann davon arbeiten. :) – bashhike

0

I verwendet mult Ilevel-Index für diese und Xs für diese. Holen Sie sich die niedrigsten Aggregate.

lvl3_grp = df.groupby(['key1', 'key2', 'key3'])['col1', 'col2'].sum() 
lvl3_grp = lvl3_grp.reset_index() 
lvl3_grp.set_index(['key1', 'key2', 'key3'], inplace=True) 

res = {} 
for k1 in lvl3_grp.index.levels[0]: 
sums = lvl3_grp.xs(k1).sum() 
lvl2_grp = lvl3_grp.xs(k1).reset_index() 
lvl2_grp.set_index(['key2', 'key3'], inplace=True) 
lvl2_dict = {} 
for k2 in lvl2_grp.index.levels[0]: 
    sums = lvl2_grp.xs(k1).sum() 

Für die letzte Stufe .index.levels[0] nicht funktionieren als einziger Index. Ich benutzte .index.values für iterable Liste und .loc innerhalb der for-Schleife für den Zugriff auf die Werte.

Ich werde die Antwort zu einem späteren Zeitpunkt erweitern.

Verwandte Themen