2013-02-25 37 views
16

Đối dataframeNhận nhóm id trở thành gấu trúc dataframe

In [2]: df = pd.DataFrame({'Name': ['foo', 'bar'] * 3, 
    ...:     'Rank': np.random.randint(0,3,6), 
    ...:     'Val': np.random.rand(6)}) 
    ...: df 
Out[2]: 
    Name Rank  Val 
0 foo  0 0.299397 
1 bar  0 0.909228 
2 foo  0 0.517700 
3 bar  0 0.929863 
4 foo  1 0.209324 
5 bar  2 0.381515 

Tôi quan tâm đến nhóm theo Tên và Xếp hạng và có thể nhận được giá trị tổng hợp

In [3]: group = df.groupby(['Name', 'Rank']) 
In [4]: agg = group.agg(sum) 
In [5]: agg 
Out[5]: 
       Val 
Name Rank   
bar 0  1.839091 
    2  0.381515 
foo 0  0.817097 
    1  0.209324 

Nhưng tôi muốn để có được một lĩnh vực trong bản gốc df có chứa số nhóm cho hàng đó, như

In [13]: df['Group_id'] = [2, 0, 2, 0, 3, 1] 
In [14]: df 
Out[14]: 
    Name Rank  Val Group_id 
0 foo  0 0.299397   2 
1 bar  0 0.909228   0 
2 foo  0 0.517700   2 
3 bar  0 0.929863   0 
4 foo  1 0.209324   3 
5 bar  2 0.381515   1 

Có e một cách tốt để làm điều này trong gấu trúc?

tôi có thể lấy nó với trăn,

In [16]: from itertools import count 
In [17]: c = count() 
In [22]: group.transform(lambda x: c.next()) 
Out[22]: 
    Val 
0 2 
1 0 
2 2 
3 0 
4 3 
5 1 

nhưng nó khá chậm trên một dataframe lớn, vì vậy tôi figured có thể có một xây dựng tốt hơn trong gấu trúc cách để làm điều này.

Trả lời

25

Rất nhiều thứ tiện dụng được lưu trữ trong đối tượng DataFrameGroupBy.grouper. Ví dụ:

>>> df = pd.DataFrame({'Name': ['foo', 'bar'] * 3, 
        'Rank': np.random.randint(0,3,6), 
        'Val': np.random.rand(6)}) 
>>> grouped = df.groupby(["Name", "Rank"]) 
>>> grouped.grouper. 
grouped.grouper.agg_series  grouped.grouper.indices 
grouped.grouper.aggregate   grouped.grouper.labels 
grouped.grouper.apply    grouped.grouper.levels 
grouped.grouper.axis    grouped.grouper.names 
grouped.grouper.compressed  grouped.grouper.ngroups 
grouped.grouper.get_group_levels grouped.grouper.nkeys 
grouped.grouper.get_iterator  grouped.grouper.result_index 
grouped.grouper.group_info  grouped.grouper.shape 
grouped.grouper.group_keys  grouped.grouper.size 
grouped.grouper.groupings   grouped.grouper.sort 
grouped.grouper.groups    

và như vậy:

>>> df["GroupId"] = df.groupby(["Name", "Rank"]).grouper.group_info[0] 
>>> df 
    Name Rank  Val GroupId 
0 foo  0 0.302482  2 
1 bar  0 0.375193  0 
2 foo  2 0.965763  4 
3 bar  2 0.166417  1 
4 foo  1 0.495124  3 
5 bar  2 0.728776  1 

Có thể có một bí danh đẹp hơn cho cho grouper.group_info[0] rình rập xung quanh nơi nào đó, nhưng điều này sẽ làm việc, dù sao.

+1

Một bí danh khác có vẻ là 'grouped.grouper.labels [0]' – beardc

+2

vấn đề duy nhất là cá mú không được ghi chép, không đảm bảo rằng nó sẽ không bị hỏng. – dashesy

+0

Ba năm sau và điều này vẫn không có giấy tờ. Nhưng thật dễ dàng để tìm ra rằng 'df.grouper' có lớp' BaseGrouper'. Phương thức 'group_info' được định nghĩa [ở đây] (https://github.com/pydata/pandas/blob/2e4da9b07d500add644257b9fa317a668cf5e332/pandas/core/groupby.py#L1549) trong đoạn mã và bạn có thể đi theo đường nhỏ một chút hơn nữa để xác nhận như sau: 1) 'group_info [1]' là một mảng các định danh nhóm duy nhất, 2) số nhận dạng nhóm cho hàng 'i' là' group_info [0] [i] 'và 3)' group_info [3 ] 'là số lượng các nhóm – shadowtalker

Các vấn đề liên quan