Pandasrame lấy hàng đầu tiên của mỗi nhóm


137

Tôi có một con gấu trúc DataFramenhư sau.

df = pd.DataFrame({'id' : [1,1,1,2,2,3,3,3,3,4,4,5,6,6,6,7,7],
                'value'  : ["first","second","second","first",
                            "second","first","third","fourth",
                            "fifth","second","fifth","first",
                            "first","second","third","fourth","fifth"]})

Tôi muốn nhóm nhóm này theo ["id", "value"] và nhận hàng đầu tiên của mỗi nhóm.

        id   value
0        1   first
1        1  second
2        1  second
3        2   first
4        2  second
5        3   first
6        3   third
7        3  fourth
8        3   fifth
9        4  second
10       4   fifth
11       5   first
12       6   first
13       6  second
14       6   third
15       7  fourth
16       7   fifth

Kết quả dự kiến

    id   value
     1   first
     2   first
     3   first
     4  second
     5  first
     6  first
     7  fourth

Tôi đã thử làm theo mà chỉ đưa ra hàng đầu tiên của DataFrame. Bất kỳ trợ giúp liên quan đến điều này được đánh giá cao.

In [25]: for index, row in df.iterrows():
   ....:     df2 = pd.DataFrame(df.groupby(['id','value']).reset_index().ix[0])

2
Tôi nhận ra câu hỏi này khá cũ, nhưng tôi khuyên bạn nên chấp nhận câu trả lời của @vital_dml vì hành vi first()liên quan đến nans là rất đáng ngạc nhiên và là điều tôi nghĩ rằng hầu hết mọi người sẽ không mong đợi.
dùng545424

Câu trả lời:


236
>>> df.groupby('id').first()
     value
id        
1    first
2    first
3    first
4   second
5    first
6    first
7   fourth

Nếu bạn cần idnhư cột:

>>> df.groupby('id').first().reset_index()
   id   value
0   1   first
1   2   first
2   3   first
3   4  second
4   5   first
5   6   first
6   7  fourth

Để có được n bản ghi đầu tiên, bạn có thể sử dụng head ():

>>> df.groupby('id').head(2).reset_index(drop=True)
    id   value
0    1   first
1    1  second
2    2   first
3    2  second
4    3   first
5    3   third
6    4  second
7    4   fifth
8    5   first
9    6   first
10   6  second
11   7  fourth
12   7   fifth

1
Cảm ơn rất nhiều! Hoạt động tốt :) Không thể có được hàng thứ hai theo cùng một cách phải không? Bạn có thể giải thích nó cũng được không?
Nilani Algiriyage

g = df.groupby (['session']) g.agg (lambda x: x.iloc [0]) điều này cũng hoạt động, không có ý tưởng nhận được giá trị thứ hai? :(
Nilani Algiriyage

giả sử rằng đếm từ đầu bạn muốn lấy số hàng top_n, sau đó dx = df.groupby ('id'). head (top_n) .reset_index (drop = True) và giả sử rằng đếm từ dưới cùng bạn muốn lấy số hàng bottom_n, sau đó dx = df.groupby ('id'). tail (bottom_n) .reset_index (drop = True)
Quetzalcoatl

3
Trong trường hợp bạn muốn n hàng cuối cùng, hãy sử dụng tail(n)(mặc định là n = 5) ( ref. ). Không nên nhầm lẫn last(), tôi đã phạm sai lầm đó.
rocarvaj

groupby('id',as_index=False)cũng giữ idnhư một cột
Richard DiSalvo

50

Điều này sẽ cung cấp cho bạn hàng thứ hai của mỗi nhóm (không được lập chỉ mục, nth (0) giống như đầu tiên ()):

df.groupby('id').nth(1) 

Tài liệu: http://pandas.pydata.org/pandas-docs/urdy/groupby.html#taking-the-nth-row-of-each-group


8
Nếu bạn muốn bội số, chẳng hạn như ba số đầu tiên, hãy sử dụng một chuỗi như nth((0,1,2))hoặc nth(range(3)).
Ronan Paixão

@ RonanPaixão: Bằng cách nào đó khi tôi đưa ra phạm vi, nó sẽ báo lỗi:TypeError: n needs to be an int or a list/set/tuple of ints
Hòa bình

@Peaceful: bạn có đang sử dụng Python 3 không? Nếu vậy, range(3)không trả về một danh sách trừ khi bạn gõ list(range(3)).
Ben

41

Tôi khuyên bạn nên sử dụng .nth(0)thay vì .first()nếu bạn cần lấy hàng đầu tiên.

Sự khác biệt giữa chúng là cách chúng xử lý NaN, do đó .nth(0)sẽ trả về hàng đầu tiên của nhóm bất kể giá trị nào trong hàng này, trong khi .first()cuối cùng sẽ trả về giá trị không đầu tiên NaNtrong mỗi cột.

Ví dụ: nếu tập dữ liệu của bạn là:

df = pd.DataFrame({'id' : [1,1,1,2,2,3,3,3,3,4,4],
            'value'  : ["first","second","third", np.NaN,
                        "second","first","second","third",
                        "fourth","first","second"]})

>>> df.groupby('id').nth(0)
    value
id        
1    first
2    NaN
3    first
4    first

>>> df.groupby('id').first()
    value
id        
1    first
2    second
3    first
4    first

1
điểm tốt. .head(1)cũng có vẻ hành xử như thế .nth(0), ngoại trừ chỉ số
Richard DiSalvo

1
Một sự khác biệt nữa là nth (0) sẽ bảo toàn chỉ mục gốc (nếu as_index = Sai), trong khi đầu tiên () sẽ không. Một lần nữa đối với tôi đây là một sự khác biệt đáng kể, vì tôi cần chính chỉ mục đó.
Oleg O

7

có lẽ đây là những gì bạn muốn

import pandas as pd
idx = pd.MultiIndex.from_product([['state1','state2'],   ['county1','county2','county3','county4']])
df = pd.DataFrame({'pop': [12,15,65,42,78,67,55,31]}, index=idx)
                pop
state1 county1   12
       county2   15
       county3   65
       county4   42
state2 county1   78
       county2   67
       county3   55
       county4   31
df.groupby(level=0, group_keys=False).apply(lambda x: x.sort_values('pop', ascending=False)).groupby(level=0).head(3)

> Out[29]: 
                pop
state1 county3   65
       county4   42
       county2   15
state2 county1   78
       county2   67
       county3   55

7

Nếu bạn chỉ cần hàng đầu tiên từ mỗi nhóm chúng tôi có thể thực hiện drop_duplicates, Lưu ý phương thức mặc định của chức năng keep='first'.

df.drop_duplicates('id')
Out[1027]: 
    id   value
0    1   first
3    2   first
5    3   first
9    4  second
11   5   first
12   6   first
15   7  fourth
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.