Cách nhóm các mục nhập DataFrame của gấu trúc theo ngày trong một cột không phải duy nhất


82

Pandas DataFramechứa cột được đặt tên "date"chứa các datetimegiá trị không phải là duy nhất . Tôi có thể nhóm các dòng trong khung này bằng cách sử dụng:

data.groupby(data['date'])

Tuy nhiên, điều này chia nhỏ dữ liệu theo các datetimegiá trị. Tôi muốn nhóm những dữ liệu này theo năm được lưu trữ trong cột "ngày". Trang này hiển thị cách nhóm theo năm trong trường hợp dấu thời gian được sử dụng làm chỉ mục, điều này không đúng trong trường hợp của tôi.

Làm cách nào để đạt được nhóm này?


Đối với những người đến đây vào năm 2017+, có một số cách mới để nhóm theo một khoảng thời gian cụ thể. Xem câu trả lời này bên dưới
Ted Petrou

Câu trả lời:


90

Tôi đang sử dụng gấu trúc 0.16.2. Điều này có hiệu suất tốt hơn trên tập dữ liệu lớn của tôi:

data.groupby(data.date.dt.year)

Sử dụng dttùy chọn và chơi xung quanh weekofyear, dayofweekv.v. trở nên dễ dàng hơn nhiều.


Đồng ý, đây dường như là cách phổ biến để truy cập các thuộc tính ngày tháng cho một chuỗi.
dancow

73

giải pháp của ecatmur sẽ hoạt động tốt. Tuy nhiên, điều này sẽ có hiệu suất tốt hơn trên các tập dữ liệu lớn:

data.groupby(data['date'].map(lambda x: x.year))

9
Tại sao bản đồ thay vì áp dụng?
Gus

1
Afaik, mapthường có một số phẩm chất hiệu quả tốt khi áp dụng các chức năng tùy ý so với chỉ sử dụng apply.
Coolio2654,

25

Điều này có thể dễ giải thích hơn với một tập dữ liệu mẫu.

Tạo dữ liệu mẫu

Giả sử chúng ta có một cột Dấu thời gian datevà một cột khác mà chúng ta muốn thực hiện tổng hợp a,.

df = pd.DataFrame({'date':pd.DatetimeIndex(['2012-1-1', '2012-6-1', '2015-1-1', '2015-2-1', '2015-3-1']),
                   'a':[9,5,1,2,3]}, columns=['date', 'a'])

df

        date  a
0 2012-01-01  9
1 2012-06-01  5
2 2015-01-01  1
3 2015-02-01  2
4 2015-03-01  3

Có một số cách để nhóm theo năm

  • Sử dụng trình truy cập dt với thuộc yeartính
  • Đưa datevào chỉ mục và sử dụng chức năng ẩn danh để truy cập năm
  • Sử dụng resamplephương pháp
  • Chuyển đổi sang thời kỳ gấu trúc

.dtngười tiếp cận với yeartài sản

Khi bạn có một cột (chứ không phải chỉ mục) của Dấu thời gian gấu trúc, bạn có thể truy cập vào nhiều thuộc tính và phương thức bổ sung khác bằng trình truy cập dt. Ví dụ:

df['date'].dt.year

0    2012
1    2012
2    2015
3    2015
4    2015
Name: date, dtype: int64

Chúng tôi có thể sử dụng điều này để tạo nhóm của mình và tính toán một số tổng hợp trên một cột cụ thể:

df.groupby(df['date'].dt.year)['a'].agg(['sum', 'mean', 'max'])

      sum  mean  max
date                
2012   14     7    9
2015    6     2    3

đưa ngày vào chỉ mục và sử dụng chức năng ẩn danh để truy cập năm

Nếu bạn đặt cột ngày làm chỉ mục, nó sẽ trở thành một DateTimeIndex với các thuộc tính và phương thức giống như trình truy cập dtcung cấp cho các cột bình thường

df1 = df.set_index('date')
df1.index.year

Int64Index([2012, 2012, 2015, 2015, 2015], dtype='int64', name='date')

Điều thú vị là khi sử dụng phương thức theo nhóm, bạn có thể chuyển cho nó một hàm. Hàm này sẽ được truyền ngầm chỉ mục của DataFrame. Vì vậy, chúng ta có thể nhận được kết quả tương tự từ trên với những điều sau:

df1.groupby(lambda x: x.year)['a'].agg(['sum', 'mean', 'max'])

      sum  mean  max
2012   14     7    9
2015    6     2    3

Sử dụng resamplephương pháp

Nếu cột ngày của bạn không có trong chỉ mục, bạn phải chỉ định cột có ontham số. Bạn cũng cần chỉ định bí danh bù đắp dưới dạng một chuỗi.

df.resample('AS', on='date')['a'].agg(['sum', 'mean', 'max'])

             sum  mean  max
date                       
2012-01-01  14.0   7.0  9.0
2013-01-01   NaN   NaN  NaN
2014-01-01   NaN   NaN  NaN
2015-01-01   6.0   2.0  3.0

Chuyển đổi sang thời kỳ gấu trúc

Bạn cũng có thể chuyển đổi cột ngày tháng sang đối tượng Dấu chấm gấu trúc. Chúng ta phải chuyển vào bí danh offset dưới dạng một chuỗi để xác định độ dài của Dấu chấm.

df['date'].dt.to_period('A')

0   2012
1   2012
2   2015
3   2015
4   2015
Name: date, dtype: object

Sau đó, chúng tôi có thể sử dụng nó như một nhóm

df.groupby(df['date'].dt.to_period('Y'))['a'].agg(['sum', 'mean', 'max'])


      sum  mean  max
2012   14     7    9
2015    6     2    3

Trong phương thức cuối cùng mà bạn sử dụng to_period('A'), đó là ('A') để làm gì?
shiv_90

2
@ Shiv_90 the 'A'is a timeeries offset-alias: pandas.pydata.org/pandas-docs/stable/…
ptim

Bạn sẽ đề xuất phương pháp nào nếu cũng cần lưu một cột 'ngày' riêng? Ví dụ: nếu tôi chạy .dt.yearphương pháp đơn giản và lưu nó trong một khung dữ liệu mới, ngày tháng sẽ được lưu dưới dạng chỉ số và điều đó sẽ trở thành vấn đề nếu nói rằng tôi cần vẽ biểu đồ dữ liệu vì cột 'ngày tháng' không thực sự ở đó mà chỉ có ba được cung cấp trong.agg()
shiv_90

13

Điều này sẽ hoạt động:

data.groupby(lambda x: data['date'][x].year)

0

điều này cũng sẽ hoạt động

data.groupby(data['date'].dt.year)


Nên hoạt động nhưng khi thực thi nó lại xuất ra vị trí của đối tượng trong bộ nhớ nhưng không có đầu ra thực. <pandas.core.groupby.DataFrameGroupBy object at 0x10d7f6438>là những gì tôi nhận được khi thực hiện.
shiv_90
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.