2016-12-26 34 views
5

Tôi đã sau dataframe:Pandas - tổng hợp, sắp xếp và nlargest bên groupby

     some_id 
2016-12-26 11:03:10  001 
2016-12-26 11:03:13  001 
2016-12-26 12:03:13  001 
2016-12-26 12:03:13  008 
2016-12-27 11:03:10  009 
2016-12-27 11:03:13  009 
2016-12-27 12:03:13  003 
2016-12-27 12:03:13  011 

Và tôi cần phải làm điều gì đó như transform ('kích thước') với loại sau đây và nhận được giá trị tối đa N. Để nhận được một cái gì đó như thế này (N = 2):

   some_id size 
2016-12-26  001  3 
       008  1 
2016-12-27  009  2 
       003  1 

Có cách nào để làm điều đó trong gấu trúc 0.19.x?

Trả lời

4

Sử dụng value_counts để tính số lượng riêng biệt sau khi nhóm trên phần date trong số DateTimeIndex của bạn. Điều này sắp xếp chúng theo thứ tự giảm dần theo mặc định.

Bạn chỉ cần sử dụng 2 hàng trên cùng của kết quả này để có được phần lớn nhất (trên cùng 2).

fnc = lambda x: x.value_counts().head(2) 
grp = df.groupby(df.index.date)['some_id'].apply(fnc).reset_index(1, name='size') 
grp.rename(columns={'level_1':'some_id'}) 

enter image description here

+0

Đó là ý tưởng đầu tiên của tôi, nhưng tôi không thể áp dụng 'head' hoặc' nlargest' sau giá trị value_counts. –

+0

* Xem bài đăng đã chỉnh sửa * –

+1

Có vẻ tốt. Tôi nghĩ chúng ta không thể thiết lập lại chỉ mục. Chỉ cần 'df.groupby (df.index.date) ['some_id'] áp dụng (lambda x: x.value_counts(). Đầu (2))' –

0

Nếu bạn đã có cột sizes, bạn có thể sử dụng như sau.

df.groupby('some_id')['size'].value_counts().groupby(level=0).nlargest(2) 

Nếu không, bạn có thể sử dụng phương pháp này.

import pandas as pd 

df = pd.DataFrame({'some_id':[1,1,1,8,9,9,3,11], 
        'some_idx':[26,26,26,26,27,27,27,27]}) 

sizes = df.groupby(['some_id', 'some_idx']).size() 

sizes.groupby(level='some_idx').nlargest(2) 

# some_idx some_id some_idx 
# 26  1  26   3 
#   8  26   1 
# 27  9  27   2 
#   3  27   1 
+0

Tôi nghĩ rằng nó rất gần nhưng tôi không có 'kích thước' cột và cần phải tính toán nó. –

+0

Ah, gotcha. Đã chỉnh sửa để phản ánh yêu cầu này. Tôi nghĩ rằng việc tạo ra một đối tượng 'groupby' mới là sự hiểu biết rõ ràng nhất. – 3novak

2

thiết lập

from io import StringIO 
import pandas as pd 

txt = """     some_id 
2016-12-26 11:03:10  001 
2016-12-26 11:03:13  001 
2016-12-26 12:03:13  001 
2016-12-26 12:03:13  008 
2016-12-27 11:03:10  009 
2016-12-27 11:03:13  009 
2016-12-27 12:03:13  003 
2016-12-27 12:03:13  011""" 

df = pd.read_csv(StringIO(txt), sep='\s{2,}', engine='python') 

df.index = pd.to_datetime(df.index) 
df.some_id = df.some_id.astype(str).str.zfill(3) 

df 

        some_id 
2016-12-26 11:03:10  001 
2016-12-26 11:03:13  001 
2016-12-26 12:03:13  001 
2016-12-26 12:03:13  008 
2016-12-27 11:03:10  009 
2016-12-27 11:03:13  009 
2016-12-27 12:03:13  003 
2016-12-27 12:03:13  011 

sử dụng nlargest

df.groupby(pd.TimeGrouper('D')).some_id.value_counts() \ 
    .groupby(level=0, group_keys=False).nlargest(2) 

      some_id 
2016-12-26 001  3 
      008  1 
2016-12-27 009  2 
      003  1 
Name: some_id, dtype: int64 
2

Bạn có thể thực hiện điều này trong một dòng.

df.resample('D')['some_id'].apply(lambda s: s.value_counts().iloc[:2]) 
Các vấn đề liên quan