web-dev-qa-db-fra.com

Existe-t-il une opération de «dissociation par» opposée à .groupby dans les pandas?

Supposons que nous prenons un pandas dataframe ...

    name  age  family
0   john    1       1
1  jason   36       1
2   jane   32       1
3   jack   26       2
4  james   30       2

Ensuite, faites une groupby() ...

group_df = df.groupby('family')
group_df = group_df.aggregate({'name': name_join, 'age': pd.np.mean})

Ensuite, effectuez une opération d'agrégation/récapitulation (dans mon exemple, ma fonction name_join Agrège les noms):

def name_join(list_names, concat='-'):
    return concat.join(list_names)

La sortie résumée groupée est donc:

        age             name
family                      
1        23  john-jason-jane
2        28       jack-james

Question:

Existe-t-il un moyen rapide et efficace d'accéder aux éléments suivants à partir du tableau agrégé?

    name  age  family
0   john   23       1
1  jason   23       1
2   jane   23       1
3   jack   28       2
4  james   28       2

(Remarque: les valeurs de la colonne age ne sont que des exemples, je ne me soucie pas des informations que je perds après la moyenne dans cet exemple spécifique)

La façon dont je pensais pouvoir le faire ne semble pas trop efficace:

  1. créer une trame de données vide
  2. de chaque ligne de group_df, séparez les noms
  3. renvoie une trame de données avec autant de lignes qu'il y a de noms dans la ligne de départ
  4. ajouter la sortie à la trame de données vide
22
mkln

L'équivalent approximatif est .reset_index(), mais il peut ne pas être utile de le considérer comme "l'opposé" de groupby().

Vous divisez une chaîne en morceaux et maintenez l'association de chaque morceau avec la "famille". Ma vieille réponse fait le travail.

Définissez simplement "famille" comme colonne d'index en premier, reportez-vous au lien ci-dessus, puis à reset_index() à la fin pour obtenir le résultat souhaité.

21
Dan Allan

Il existe plusieurs façons d'annuler DataFrame.groupby, une façon consiste à effectuer DataFrame.groupby.filter (lambda x: True), cela revient au DataFrame d'origine.

0
xuancong84

Voici un exemple complet qui récupère la trame de données d'origine de l'objet groupé

def name_join(list_names, concat='-'):
    return concat.join(list_names)

print('create dataframe\n')
df = pandas.DataFrame({'name':['john', 'jason', 'jane', 'jack', 'james'], 'age':[1,36,32,26,30], 'family':[1,1,1,2,2]})
df.index.name='indexer'
print(df)
print('create group_by object')
group_obj_df = df.groupby('family')
print(group_obj_df)

print('\nrecover grouped df')
group_joined_df = group_obj_df.aggregate({'name': name_join, 'age': 'mean'})
group_joined_df


create dataframe

          name  age  family
indexer                    
0         john    1       1
1        jason   36       1
2         jane   32       1
3         jack   26       2
4        james   30       2
create group_by object
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fbfdd9dd048>

recover grouped df 
                   name  age
family                      
1       john-jason-jane   23
2            jack-james   28
print('\nRecover the original dataframe')
print(pandas.concat([group_obj_df.get_group(key) for key in group_obj_df.groups]))

Recover the original dataframe
          name  age  family
indexer                    
0         john    1       1
1        jason   36       1
2         jane   32       1
3         jack   26       2
4        james   30       2
0
Skysail