Gần đây tôi đã bắt đầu sử dụng thư viện Pandas tuyệt vời của Python làm công cụ phân tích dữ liệu và trong khi tìm kiếm sự chuyển đổi từ dữ liệu tuyệt vời của R. thư viện bảng đôi khi làm tôi bực bội, tôi đang tìm đường và thấy hầu hết mọi thứ đều hoạt động khá tốt
Một khía cạnh mà tôi đã khám phá gần đây là nhiệm vụ nhóm các khung dữ liệu lớn theo các biến khác nhau và áp dụng các hàm tóm tắt trên mỗi nhóm. Điều này được thực hiện trong Pandas bằng cách sử dụng các hàm “groupby[]” và “agg[]” của các đối tượng DataFrame của Panda
Cập nhật. phiên bản gấu trúc 0. 20. 1 vào tháng 5 năm 2017 đã thay đổi API tổng hợp và nhóm. Bài đăng này đã được cập nhật để phản ánh những thay đổi mới
Khung dữ liệu mẫu
Để chứng minh tính hiệu quả và đơn giản của các lệnh nhóm, chúng tôi sẽ cần một số dữ liệu. Đối với tập dữ liệu mẫu, tôi đã trích xuất hồ sơ sử dụng điện thoại di động của riêng mình. Tôi đã phân tích loại dữ liệu này bằng Pandas trong quá trình làm việc trên KillBiller. Nếu bạn muốn làm theo – tệp csv đầy đủ có sẵn tại đây
Tập dữ liệu chứa 830 mục từ nhật ký điện thoại di động của tôi trong tổng thời gian 5 tháng. Tệp CSV có thể được tải vào DataFrame của gấu trúc bằng pandas. Khung dữ liệu. from_csv[] và trông như thế này
datedurationitemmonthnetworknetwork_type015/10/14 06. 5834. 429data2014-11datadata115/10/14 06. 5813. 000call2014-11Vodafonemobile215/10/14 14. 4623. 000call2014-11Meteormobile315/10/14 14. 484. 000call2014-11Tescomobile415/10/14 17. 274. 000call2014-11Tescomobile515/10/14 18. 554. 000call2014-11Tescomobile616/10/14 06. 5834. 429data2014-11datadata716/10/14 15. 01602. 000call2014-11Threemobile816/10/14 15. 121050. 000call2014-11Threemobile916/10/14 15. 3019. 000call2014-11thư thoạithư thoại1016/10/14 16. 211183. 000call2014-11Threemobile1116/10/14 22. 181. 000sms2014-11Meteormobile………………Dữ liệu tệp CSV mẫu chứa ngày và thời lượng của các cuộc gọi điện thoại được thực hiện trên điện thoại di động của tôi.Các cột chính trong tệp là
- ngày tháng. Ngày và thời gian nhập cảnh
- khoảng thời gian. Thời lượng [tính bằng giây] cho mỗi cuộc gọi, lượng dữ liệu [tính bằng MB] cho mỗi mục nhập dữ liệu và số lượng tin nhắn được gửi [thường là 1] cho mỗi mục sms
- mục. Mô tả về sự kiện đang xảy ra – có thể là cuộc gọi, tin nhắn hoặc dữ liệu
- tháng. Tháng thanh toán mà mỗi mục nhập thuộc về - có dạng 'YYYY-MM'
- mạng. Mạng di động đã được gọi/nhắn tin cho mỗi mục nhập
- dạng kết nối. Số được gọi là số di động, quốc tế ['thế giới'], thư thoại, điện thoại cố định hay số khác ['đặc biệt']
Số điện thoại đã bị xóa để bảo mật. Cột ngày có thể được phân tích cú pháp bằng thư viện dateutil cực kỳ tiện dụng
import pandas as pd import dateutil # Load data from csv file data = pd.DataFrame.from_csv['phone_data.csv'] # Convert date from string to date times data['date'] = data['date'].apply[dateutil.parser.parse, dayfirst=True]
Tóm tắt DataFrame
Khi dữ liệu đã được tải vào Python, Pandas giúp việc tính toán các số liệu thống kê khác nhau trở nên rất đơn giản. Ví dụ: giá trị trung bình, tối đa, tối thiểu, độ lệch chuẩn và hơn thế nữa cho các cột có thể dễ dàng tính toán được
# How many rows the dataset data['item'].count[] Out[38]: 830 # What was the longest phone call / data entry? data['duration'].max[] Out[39]: 10528.0 # How many seconds of phone calls are recorded in total? data['duration'][data['item'] == 'call'].sum[] Out[40]: 92321.0 # How many entries are there for each month? data['month'].value_counts[] Out[41]: 2014-11 230 2015-01 205 2014-12 157 2015-02 137 2015-03 101 dtype: int64 # Number of non-null unique network entries data['network'].nunique[] Out[42]: 9
Nhu cầu về chức năng tùy chỉnh là tối thiểu trừ khi bạn có yêu cầu rất cụ thể. Đầy đủ các số liệu thống kê cơ bản có thể tính toán nhanh chóng và được tích hợp vào gói Pandas cơ sở là
FunctionDescriptioncountNumber of non-null observationssumSum of valuesmeanMean of valuesmadMean absolute deviationmedianArithmetic median of valuesminMinimummaxMaximummodeModeabsAbsolute ValueprodProduct of valuesstdUnbiased standard deviationvarUnbiased variancesemUnbiased standard error of the meanskewUnbiased skewness [3rd moment]kurtUnbiased kurtosis [4th moment]quantileSample quantile [value at %]cumsumCumulative sumcumprodCumulative productcummaxCumulative maximumcumminCumulative minimumCác. description[] là một công cụ tóm tắt hữu ích sẽ nhanh chóng hiển thị số liệu thống kê cho bất kỳ biến hoặc nhóm nào mà nó được áp dụng cho. Đầu ra description[] khác nhau tùy thuộc vào việc bạn áp dụng nó cho cột số hay ký tự
Tóm tắt các nhóm trong DataFrame
Bạn sẽ có thêm sức mạnh bằng cách làm chủ chức năng “groupby[]” của Pandas. Về cơ bản, Groupby chia dữ liệu thành các nhóm khác nhau tùy thuộc vào một biến bạn chọn. Ví dụ: dữ liệu biểu thức. groupby['month'] sẽ chia DataFrame hiện tại của chúng tôi theo tháng
Hàm groupby[] trả về một đối tượng GroupBy, nhưng về cơ bản mô tả cách phân chia các hàng của tập dữ liệu gốc. đối tượng GroupBy. biến nhóm là một từ điển có khóa là các nhóm duy nhất được tính toán và các giá trị tương ứng là các nhãn trục thuộc mỗi nhóm. Ví dụ
data.groupby[['month']].groups.keys[] Out[59]: ['2014-12', '2014-11', '2015-02', '2015-03', '2015-01'] len[data.groupby[['month']].groups['2014-11']] Out[61]: 230
Các hàm như max[], min[], mean[], first[], last[] có thể nhanh chóng được áp dụng cho đối tượng GroupBy để lấy số liệu thống kê tóm tắt cho mỗi nhóm – một hàm vô cùng hữu ích. Chức năng này tương tự như các thư viện dplyr và plyr cho R. Các biến khác nhau có thể được loại trừ/bao gồm từ mỗi yêu cầu tóm tắt
# Get the first entry for each month data.groupby['month'].first[] Out[69]: date duration item network network_type month 2014-11 2014-10-15 06:58:00 34.429 data data data 2014-12 2014-11-13 06:58:00 34.429 data data data 2015-01 2014-12-13 06:58:00 34.429 data data data 2015-02 2015-01-13 06:58:00 34.429 data data data 2015-03 2015-02-12 20:15:00 69.000 call landline landline # Get the sum of the durations per month data.groupby['month']['duration'].sum[] Out[70]: month 2014-11 26639.441 2014-12 14641.870 2015-01 18223.299 2015-02 15522.299 2015-03 22750.441 Name: duration, dtype: float64 # Get the number of dates / entries in each month data.groupby['month']['date'].count[] Out[74]: month 2014-11 230 2014-12 157 2015-01 205 2015-02 137 2015-03 101 Name: date, dtype: int64 # What is the sum of durations, for calls only, to each network data[data['item'] == 'call'].groupby['network']['duration'].sum[] Out[78]: network Meteor 7200 Tesco 13828 Three 36464 Vodafone 14621 landline 18433 voicemail 1775 Name: duration, dtype: float64
Bạn cũng có thể nhóm theo nhiều biến, cho phép truy vấn phức tạp hơn
# How many calls, sms, and data entries are in each month? data.groupby[['month', 'item']]['date'].count[] Out[76]: month item 2014-11 call 107 data 29 sms 94 2014-12 call 79 data 30 sms 48 2015-01 call 88 data 31 sms 86 2015-02 call 67 data 31 sms 39 2015-03 call 47 data 29 sms 25 Name: date, dtype: int64 # How many calls, texts, and data are sent per month, split by network_type? data.groupby[['month', 'network_type']]['date'].count[] Out[82]: month network_type 2014-11 data 29 landline 5 mobile 189 special 1 voicemail 6 2014-12 data 30 landline 7 mobile 108 voicemail 8 world 4 2015-01 data 31 landline 11 mobile 160 ....
Định dạng đầu ra theo nhóm – Sê-ri hay DataFrame?
Đầu ra từ hoạt động nhóm và tổng hợp khác nhau giữa Pandas Series và Pandas Dataframes, điều này có thể gây nhầm lẫn cho người dùng mới. Theo nguyên tắc thông thường, nếu bạn tính toán nhiều hơn một cột kết quả, kết quả của bạn sẽ là một Dataframe. Đối với một cột kết quả, theo mặc định, hàm agg sẽ tạo ra một Chuỗi
Bạn có thể thay đổi điều này bằng cách chọn cột thao tác khác đi
# produces Pandas Series data.groupby['month']['duration'].sum[] # Produces Pandas DataFrame data.groupby['month'][['duration']].sum[]
Đầu ra theo nhóm sẽ có một chỉ mục hoặc đa chỉ mục trên các hàng tương ứng với các biến nhóm đã chọn của bạn. Để tránh đặt chỉ mục này, hãy chuyển “as_index=False” cho thao tác nhóm
data.groupby['month', as_index=False].agg[{"duration": "sum"}]
Nhiều thống kê cho mỗi nhóm
Đoạn cú pháp cuối cùng mà chúng ta sẽ kiểm tra là hàm “agg[]” cho Pandas. Chức năng tổng hợp được cung cấp bởi hàm agg[] cho phép tính toán nhiều số liệu thống kê cho mỗi nhóm trong một lần tính toán.
Áp dụng một hàm duy nhất cho các cột trong nhóm
Hướng dẫn tổng hợp được cung cấp dưới dạng danh sách hoặc từ điển python. Các khóa từ điển được sử dụng để chỉ định các cột mà bạn muốn thực hiện các thao tác và các giá trị từ điển để chỉ định chức năng sẽ chạy
Ví dụ
# Group the data frame by month and item and extract a number of stats from each group data.groupby[ ['month', 'item'] ].agg[ { 'duration':sum, # Sum duration per group 'network_type': "count", # get the count of networks 'date': 'first' # get the first date per group } ]
Cú pháp từ điển tổng hợp linh hoạt và có thể được xác định trước khi thao tác. Bạn cũng có thể xác định các hàm nội tuyến bằng cách sử dụng các hàm “lambda” để trích xuất số liệu thống kê không được cung cấp bởi các tùy chọn tích hợp
________số 8Áp dụng nhiều hàm cho các cột theo nhóm
Để áp dụng nhiều hàm cho một cột trong dữ liệu được nhóm của bạn, hãy mở rộng cú pháp ở trên để chuyển vào danh sách các hàm dưới dạng giá trị trong khung dữ liệu tổng hợp của bạn. Xem bên dưới
# Group the data frame by month and item and extract a number of stats from each group data.groupby[ ['month', 'item'] ].agg[ { # Find the min, max, and sum of the duration column 'duration': [min, max, sum], # find the number of network type entries 'network_type': "count", # minimum, first, and number of unique dates 'date': [min, 'first', 'nunique'] } ]
tổng hợp [. ] cú pháp linh hoạt và dễ sử dụng. Hãy nhớ rằng bạn có thể chuyển các hàm tùy chỉnh và hàm lambda vào danh sách các phép tính tổng hợp của mình và mỗi hàm sẽ được chuyển các giá trị từ cột trong dữ liệu được nhóm của bạn
Đổi tên các cột tổng hợp được nhóm
Chúng tôi sẽ kiểm tra hai phương pháp để nhóm Dataframes và đổi tên cột kết quả trong công việc của bạn
Khuyến khích. Tập hợp được đặt tên Tuple
Được giới thiệu trong Pandas 0. 25. 0, tập hợp theo nhóm với ghi nhãn lại được hỗ trợ bằng cách sử dụng "tập hợp được đặt tên" với các bộ dữ liệu đơn giản. Các bộ dữ liệu trong Python được dùng để cung cấp tên cột để làm việc trên đó, cùng với hàm để áp dụng.
Ví dụ
# How many rows the dataset data['item'].count[] Out[38]: 830 # What was the longest phone call / data entry? data['duration'].max[] Out[39]: 10528.0 # How many seconds of phone calls are recorded in total? data['duration'][data['item'] == 'call'].sum[] Out[40]: 92321.0 # How many entries are there for each month? data['month'].value_counts[] Out[41]: 2014-11 230 2015-01 205 2014-12 157 2015-02 137 2015-03 101 dtype: int64 # Number of non-null unique network entries data['network'].nunique[] Out[42]: 90
Để đặt tên rõ ràng hơn, Pandas cũng cung cấp bộ dữ liệu có tên NamedAggregation, có thể được sử dụng để đạt được điều tương tự như bộ dữ liệu bình thường
# How many rows the dataset data['item'].count[] Out[38]: 830 # What was the longest phone call / data entry? data['duration'].max[] Out[39]: 10528.0 # How many seconds of phone calls are recorded in total? data['duration'][data['item'] == 'call'].sum[] Out[40]: 92321.0 # How many entries are there for each month? data['month'].value_counts[] Out[41]: 2014-11 230 2015-01 205 2014-12 157 2015-02 137 2015-03 101 dtype: int64 # Number of non-null unique network entries data['network'].nunique[] Out[42]: 91
Lưu ý rằng trong các phiên bản Pandas sau khi phát hành, việc áp dụng các hàm lambda chỉ hoạt động cho các tập hợp được đặt tên này khi chúng là hàm duy nhất được áp dụng cho một cột, nếu không sẽ gây ra lỗi KeyError
Đổi tên chỉ mục bằng droplevel và ravel
Khi nhiều số liệu thống kê được tính toán trên các cột, khung dữ liệu kết quả sẽ có nhiều chỉ mục được đặt trên trục cột. Có thể khó làm việc với đa chỉ mục và tôi thường phải đổi tên các cột sau khi thao tác theo nhóm
Một tùy chọn là bỏ cấp cao nhất [sử dụng. droplevel] của đa chỉ mục mới được tạo trên các cột bằng cách sử dụng
# How many rows the dataset data['item'].count[] Out[38]: 830 # What was the longest phone call / data entry? data['duration'].max[] Out[39]: 10528.0 # How many seconds of phone calls are recorded in total? data['duration'][data['item'] == 'call'].sum[] Out[40]: 92321.0 # How many entries are there for each month? data['month'].value_counts[] Out[41]: 2014-11 230 2015-01 205 2014-12 157 2015-02 137 2015-03 101 dtype: int64 # Number of non-null unique network entries data['network'].nunique[] Out[42]: 92
Tuy nhiên, cách tiếp cận này làm mất tên cột ban đầu, chỉ để lại tên hàm làm tiêu đề cột. Một cách tiếp cận gọn gàng hơn, như một độc giả đã gợi ý cho tôi, là sử dụng phương thức ravel[] trên các cột được nhóm. Ravel[] biến đa chỉ mục Pandas thành một mảng đơn giản hơn, mà chúng ta có thể kết hợp thành các tên cột hợp lý
# How many rows the dataset data['item'].count[] Out[38]: 830 # What was the longest phone call / data entry? data['duration'].max[] Out[39]: 10528.0 # How many seconds of phone calls are recorded in total? data['duration'][data['item'] == 'call'].sum[] Out[40]: 92321.0 # How many entries are there for each month? data['month'].value_counts[] Out[41]: 2014-11 230 2015-01 205 2014-12 157 2015-02 137 2015-03 101 dtype: int64 # Number of non-null unique network entries data['network'].nunique[] Out[42]: 93
Dictionary groupby format
Đã có những thay đổi đáng kể đối với chức năng tổng hợp Pandas vào tháng 5 năm 2017. Đổi tên các biến bằng cách sử dụng từ điển trong hàm agg[] như trong sơ đồ bên dưới không được chấp nhận/xóa khỏi Pandas – xem ghi chú
Trong các bản phát hành Pandas cũ hơn [< 0. 20. 1], có thể đổi tên các cột mới được tính toán thông qua các từ điển lồng nhau hoặc bằng cách chuyển danh sách các hàm cho một cột. Ví dụ cuối cùng của chúng tôi tính toán nhiều giá trị từ cột thời lượng và đặt tên cho kết quả một cách thích hợp. Lưu ý rằng kết quả có tiêu đề cột đa chỉ mục
Lưu ý rằng cú pháp này sẽ không còn hoạt động đối với các cài đặt mới của Python Pandas.
# How many rows the dataset data['item'].count[] Out[38]: 830 # What was the longest phone call / data entry? data['duration'].max[] Out[39]: 10528.0 # How many seconds of phone calls are recorded in total? data['duration'][data['item'] == 'call'].sum[] Out[40]: 92321.0 # How many entries are there for each month? data['month'].value_counts[] Out[41]: 2014-11 230 2015-01 205 2014-12 157 2015-02 137 2015-03 101 dtype: int64 # Number of non-null unique network entries data['network'].nunique[] Out[42]: 94
Tóm tắt về Python Pandas Grouping
Chức năng nhóm trong Pandas được ghi lại rõ ràng trong các tài liệu chính thức và hoạt động ở tốc độ ngang bằng [trừ khi bạn có dữ liệu lớn và kén chọn mili giây của mình] với dữ liệu của R. thư viện bảng và dplyr
Nếu bạn quan tâm đến một ví dụ khác để thực hành, tôi đã sử dụng các kỹ thuật tương tự này để phân tích dữ liệu thời tiết cho bài đăng này và tôi đã đặt "hướng dẫn" tại đây
Có rất nhiều tài nguyên trực tuyến về chức năng này và tôi khuyên bạn nên thực sự chinh phục cú pháp này nếu bạn đang sử dụng Pandas một cách nghiêm túc tại bất kỳ thời điểm nào