Comment accéder à la frameframe groupby correspondante dans un objet groupby à l'aide de la clé? Avec le groupby suivant:
Rand = np.random.RandomState(1)
df = pd.DataFrame({'A': ['foo', 'bar'] * 3,
'B': Rand.randn(6),
'C': Rand.randint(0, 20, 6)})
gb = df.groupby(['A'])
Je peux parcourir pour obtenir les clés et les groupes:
In [11]: for k, gp in gb:
print 'key=' + str(k)
print gp
key=bar
A B C
1 bar -0.611756 18
3 bar -1.072969 10
5 bar -2.301539 18
key=foo
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
J'aimerais pouvoir faire quelque chose comme
In [12]: gb['foo']
Out[12]:
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
Mais quand je fais ça (enfin, en fait je dois faire gb[('foo',)]
), je reçois cette chose bizarre pandas.core.groupby.DataFrameGroupBy
qui ne semble pas avoir de méthode correspondant au DataFrame que je veux.
Le mieux que je puisse penser est
In [13]: def gb_df_key(gb, key, orig_df):
ix = gb.indices[key]
return orig_df.ix[ix]
gb_df_key(gb, 'foo', df)
Out[13]:
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
mais c’est un peu vilain, vu la façon dont Nice pandas est habituellement à ces choses.
Quelle est la manière inhérente de faire cela?
Vous pouvez utiliser la méthode get_group
:
_In [21]: gb.get_group('foo')
Out[21]:
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
_
Remarque: cela ne nécessite pas de créer un dictionnaire intermédiaire/une copie de chaque sous-trame de données pour chaque groupe. La mémoire sera donc beaucoup plus efficace que la création du dictionnaire naïf avec dict(iter(gb))
. En effet, il utilise des structures de données déjà disponibles dans l'objet groupby.
Vous pouvez sélectionner différentes colonnes en utilisant le groupby slicing:
_In [22]: gb[["A", "B"]].get_group("foo")
Out[22]:
A B
0 foo 1.624345
2 foo -0.528172
4 foo 0.865408
In [23]: gb["C"].get_group("foo")
Out[23]:
0 5
2 11
4 14
Name: C, dtype: int64
_
Wes McKinney (auteur de pandas) dans Python for Data Analysis fournit la recette suivante:
groups = dict(list(gb))
qui renvoie un dictionnaire dont les clés sont les étiquettes de votre groupe et dont les valeurs sont DataFrames, c.-à-d.
groups['foo']
donnera ce que vous cherchez:
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
Plutôt que
gb.get_group('foo')
Je préfère utiliser gb.groups
df.loc[gb.groups['foo']]
Parce que de cette façon, vous pouvez également choisir plusieurs colonnes. par exemple:
df.loc[gb.groups['foo'],('A','B')]
gb = df.groupby(['A'])
gb_groups = grouped_df.groups
Si vous recherchez des objets groupby sélective, faites: gb_groups.keys () et entrez la clé souhaitée dans la liste de clés suivante.
gb_groups.keys()
key_list = [key1, key2, key3 and so on...]
for key, values in gb_groups.iteritems():
if key in key_list:
print df.ix[values], "\n"
Je cherchais un moyen d'échantillonner quelques membres du groupe. Par obj - je devais répondre à la question affichée pour que cela soit fait.
grouped = df.groupby('some_key')
sampled_df_i = random.sample(grouped.indicies, N)
df_list = map(lambda df_i: grouped.get_group(df_i), sampled_df_i)
sampled_df = pd.concat(df_list, axis=0, join='outer')