Cara mengakses grup panda dengan bingkai data dengan kunci

154

Bagaimana cara mengakses kerangka grup yang sesuai dengan data di objek grup dengan tombol?

Dengan grup berikut:

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'])

Saya bisa mengulanginya untuk mendapatkan kunci dan grup:

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

Saya ingin dapat mengakses grup dengan kuncinya:

In [12]: gb['foo']
Out[12]:  
     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14

Tetapi ketika saya mencoba melakukan itu dengan gb[('foo',)]saya mendapatkan pandas.core.groupby.DataFrameGroupBybenda aneh ini yang sepertinya tidak memiliki metode yang sesuai dengan DataFrame yang saya inginkan.

Yang terbaik yang bisa saya pikirkan adalah:

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  

tapi ini agak menjijikkan, mengingat betapa baiknya panda biasanya dalam hal ini.
Apa cara bawaan untuk melakukan ini?

jenggot
sumber

Jawaban:

192

Anda dapat menggunakan get_groupmetode ini:

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

Catatan: Ini tidak memerlukan pembuatan kamus perantara / salinan setiap subdataframe untuk setiap grup, jadi akan jauh lebih hemat memori dengan membuat kamus naif dict(iter(gb)). Ini karena menggunakan struktur data yang sudah tersedia di objek groupby.


Anda dapat memilih kolom yang berbeda menggunakan grup dengan memotong:

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
Andy Hayden
sumber
72

Wes McKinney (penulis panda) dalam Python untuk Analisis Data memberikan resep berikut:

groups = dict(list(gb))

yang mengembalikan kamus yang kuncinya adalah label grup Anda dan yang nilainya adalah DataFrames, yaitu

groups['foo']

akan menghasilkan apa yang Anda cari:

     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14
JD Margulici
sumber
1
Terima kasih, ini sangat berguna. Bagaimana saya bisa memodifikasi kode untuk membuat groups = dict(list(gb))kolom toko saja C? Katakanlah saya tidak tertarik pada kolom lain dan karena itu tidak ingin menyimpannya.
Zhubarb
5
Jawaban:dict(list( df.groupby(['A'])['C'] ))
Zhubarb
4
Catatan: lebih efisien (tapi setara) untuk digunakan dict(iter(g)). (meskipun get_groupcara terbaik / karena tidak melibatkan pembuatan kamus / membuat Anda dalam panda!: D)
Andy Hayden
Saya tidak dapat menggunakan grup (dict (daftar (gb)) tetapi Anda dapat membuat kamus dengan cara berikut: gb_dict = {str(indx): str(val) for indx in gb.indx for val in gb.some_key}dan kemudian mengambil nilai melaluigb_dict[some_key]
user2476665
Cukup gunakan get_group(), resep ini belum diperlukan selama bertahun-tahun.
smci
20

Daripada

gb.get_group('foo')

Saya lebih suka menggunakan gb.groups

df.loc[gb.groups['foo']]

Karena dengan cara ini Anda dapat memilih banyak kolom juga. sebagai contoh:

df.loc[gb.groups['foo'],('A','B')]
LegitMe
sumber
4
Catatan: Anda dapat memilih kolom yang berbeda menggunakan gb[["A", "B"]].get_group("foo").
Andy Hayden
6
gb = df.groupby(['A'])

gb_groups = grouped_df.groups

Jika Anda mencari objek groupby selektif kemudian, lakukan: gb_groups.keys (), dan masukkan kunci yang diinginkan ke key_list berikut ..

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"
Surya
sumber
1

Saya sedang mencari cara untuk mencicipi beberapa anggota keberatan GroupBy - harus menjawab pertanyaan yang diposting untuk menyelesaikan ini.

buat objek groupby

grouped = df.groupby('some_key')

pilih N dataframe dan ambil indeksnya

sampled_df_i  = random.sample(grouped.indicies, N)

ambil grup

df_list  = map(lambda df_i: grouped.get_group(df_i), sampled_df_i)

opsional - ubah semuanya menjadi objek dataframe tunggal

sampled_df = pd.concat(df_list, axis=0, join='outer')
meyerson
sumber
1
Ini tidak berhasil:sampled_df_i = random.sample(grouped.indicies, N)
irene
@irene - dapatkah Anda memberikan tautan ke konteks contoh / lebih panjang?
meyerson
Saya mendapatkan kesalahan berikut:AttributeError: 'DataFrameGroupBy' object has no attribute 'indicies'
irene