Làm thế nào để truy cập dataframe của nhóm gấu trúc bằng khóa


154

Làm cách nào để tôi truy cập vào khung dữ liệu nhóm tương ứng trong một đối tượng nhóm bằng khóa?

Với các nhóm sau:

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

Tôi có thể lặp qua nó để lấy các khóa và nhóm:

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

Tôi muốn có thể truy cập một nhóm bằng khóa của nó:

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

Nhưng khi tôi thử làm điều đó với gb[('foo',)]tôi, tôi nhận được pandas.core.groupby.DataFrameGroupBythứ đối tượng kỳ lạ này dường như không có bất kỳ phương thức nào tương ứng với DataFrame mà tôi muốn.

Điều tốt nhất tôi có thể nghĩ là:

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  

nhưng điều này thật khó chịu, xem xét những con gấu trúc đẹp thường ở những thứ này như thế nào.
Cách tích hợp để làm điều này là gì?

Câu trả lời:


192

Bạn có thể sử dụng get_groupphương pháp:

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

Lưu ý: Điều này không yêu cầu tạo một từ điển trung gian / bản sao của mọi khung con cho mỗi nhóm, do đó sẽ hiệu quả hơn về bộ nhớ khi tạo từ điển ngây thơ dict(iter(gb)). Điều này là do nó sử dụng các cấu trúc dữ liệu đã có sẵn trong đối tượng nhóm.


Bạn có thể chọn các cột khác nhau bằng cách sử dụng cắt theo nhóm:

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

72

Wes McKinney (tác giả của gấu trúc) trong Python for Data Phân tích cung cấp công thức sau:

groups = dict(list(gb))

trong đó trả về một từ điển có khóa là nhãn nhóm của bạn và có giá trị là DataFrames, nghĩa là

groups['foo']

sẽ mang lại những gì bạn đang tìm kiếm:

     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14

1
Cảm ơn bạn, điều này rất hữu ích. Làm thế nào tôi có thể sửa đổi mã để groups = dict(list(gb))chỉ lưu trữ cột C? Giả sử tôi không quan tâm đến các cột khác và do đó không muốn lưu trữ chúng.
Zhubarb

5
Trả lời:dict(list( df.groupby(['A'])['C'] ))
Zhubarb

4
Lưu ý: sử dụng hiệu quả hơn (nhưng tương đương) dict(iter(g)). (mặc dù get_grouplà cách tốt nhất / vì nó không liên quan đến việc tạo từ điển / giữ bạn trong gấu trúc !: D)
Andy Hayden

Tôi đã không thể sử dụng các nhóm (dict (danh sách (gb)) nhưng bạn có thể tạo ra một từ điển theo cách sau: gb_dict = {str(indx): str(val) for indx in gb.indx for val in gb.some_key}và sau đó lấy giá trị thông quagb_dict[some_key]
user2476665

Chỉ cần sử dụng get_group(), công thức này đã không cần thiết trong nhiều năm.
smci

20

Thay vì

gb.get_group('foo')

Tôi thích sử dụng gb.groups

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

Bởi vì theo cách này, bạn có thể chọn nhiều cột là tốt. ví dụ:

df.loc[gb.groups['foo'],('A','B')]

4
Lưu ý: Bạn có thể chọn các cột khác nhau bằng cách sử dụng gb[["A", "B"]].get_group("foo").
Andy Hayden

6
gb = df.groupby(['A'])

gb_groups = grouped_df.groups

Nếu bạn đang tìm kiếm các đối tượng nhóm chọn lọc thì hãy làm: gb_groups.keys () và nhập khóa mong muốn vào key_list sau ..

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"

1

Tôi đang tìm cách để lấy mẫu một vài thành viên của GroupBy obj - đã phải giải quyết câu hỏi được đăng để thực hiện điều này.

tạo đối tượng nhóm

grouped = df.groupby('some_key')

chọn N dataframes và lấy chỉ thị của chúng

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

lấy các nhóm

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

tùy chọn - biến tất cả trở lại thành một đối tượng khung dữ liệu

sampled_df = pd.concat(df_list, axis=0, join='outer')

1
Điều này không hoạt động:sampled_df_i = random.sample(grouped.indicies, N)
irene

@irene - bạn có thể cung cấp một liên kết đến một ví dụ dài hơn / nhiều ngữ cảnh hơn không?
meyerson

Tôi nhận được lỗi sau:AttributeError: 'DataFrameGroupBy' object has no attribute 'indicies'
irene
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.