Lựa chọn dữ liệu trong dãy¶
Như chúng ta đã thấy ở phần trước, một đối tượng Series
hoạt động theo nhiều cách giống như một mảng 1 chiều NumPy và cũng giống như một từ điển Python tiêu chuẩn.Nếu chúng ta giữ hai điểm tương đồng này trong đầu, nó sẽ giúp chúng ta hiểu các mẫu của việc chỉ mục và lựa chọn dữ liệu trong các mảng này.
Series như một từ điển¶
Tương tự như một từ điển, đối tượng Series
cung cấp một ánh xạ từ một bộ các khóa đến một bộ các giá trị:
import pandas as pddata = pd.Series([0.25, 0.5, 0.75, 1.0], index=['a', 'b', 'c', 'd'])data
a 0.25b 0.50c 0.75d 1.00dtype: float64
data['b']
0.5
Chúng ta cũng có thể sử dụng các biểu thức và phương thức giống như từ điển trong Python để kiểm tra các khóa/chỉ mục và giá trị:
'a' in data
True
data.keys()
Index(['a', 'b', 'c', 'd'], dtype='object')
list(data.items())
[('a', 0.25), ('b', 0.5), ('c', 0.75), ('d', 1.0)]
Đối tượng Series
thậm chí có thể được sửa đổi bằng cú pháp giống như từ điển.Tương tự như việc bạn có thể mở rộng một từ điển bằng cách gán cho một khóa mới, bạn cũng có thể mở rộng một Series
bằng cách gán cho một giá trị chỉ mục mới:
data['e'] = 1.25data
a 0.25b 0.50c 0.75d 1.00e 1.25dtype: float64
Sự thay đổi dễ dàng của các đối tượng này là một tính năng tiện lợi: dưới hậu trường, Pandas đang đưa ra quyết định về bố cục bộ nhớ và sao chép dữ liệu có thể cần xảy ra; người dùng thông thường không cần lo lắng về những vấn đề này.
Chuỗi dưới dạng một mảng một chiều¶
Một Series
xây dựng trên giao diện giống như từ điển này và cung cấp lựa chọn mục bằng cách sử dụng các cơ chế cơ bản giống như mảng NumPy – tức là lát, lọc, và lập chỉ mục phong cách đặc biệt.Ví dụ về những thứ này như sau:
# slicing by explicit indexdata['a':'c']
a 0.25b 0.50c 0.75dtype: float64
# slicing by implicit integer indexdata[0:2]
a 0.25b 0.50dtype: float64
# maskingdata[(data > 0.3) & (data < 0.8)]
b 0.50c 0.75dtype: float64
# fancy indexingdata[['a', 'e']]
a 0.25e 1.25dtype: float64
Trong số đó, phần chia có thể là nguồn gây nhầm lẫn nhất.Chú ý rằng khi chia bằng chỉ số tường minh (ví dụ: data['a':'c']
), chỉ số cuối cùng được bao gồm trong phần chia, trong khi khi chia bằng chỉ số ngầm định (ví dụ: data[0:2]
), chỉ số cuối cùng được loại trừ khỏi phần chia.
Indexers: loc, iloc, và ix¶
Các quy ước chia trích và chia chỉ số này có thể gây nhầm lẫn.Ví dụ, nếu Serires
của bạn có một chỉ mục số nguyên rõ ràng, một hoạt động chia chỉ số như data[1]
sẽ sử dụng các chỉ mục rõ ràng, trong khi một hoạt động chia trích như data[1:3]
sẽ sử dụng chỉ mục kiểu Python ngầm định.
data = pd.Series(['a', 'b', 'c'], index=[1, 3, 5])data
1 a3 b5 cdtype: object
# explicit index when indexingdata[1]
'a'
# implicit index when slicingdata[1:3]
3 b5 cdtype: object
Vì sự mơ hồ này trong trường hợp các chỉ số nguyên, Pandas cung cấp một số thuộc tính \em>indexer đặc biệt để hiển thị một số hệ thống chỉ mục cụ thể.Đây không phải là các phương thức hoạt động, mà là những thuộc tính mà tiết lộ một giao diện cắt bỏ cụ thể đến dữ liệu trong Series
.
Đầu tiên, thuộc tính loc
cho phép chỉ mục và cắt nguyên lúc luôn tham chiếu đến chỉ mục cụ thể:
data.loc[1]
'a'
data.loc[1:3]
1 a3 bdtype: object
Thuộc tính iloc
cho phép truy cập và cắt các phần tử dựa trên chỉ mục ngầm định theo kiểu Python:
data.iloc[1]
'b'
data.iloc[1:3]
3 b5 cdtype: object
Một thuộc tính chỉ mục thứ ba, ix
, là một sự kết hợp của hai thuộc tính trên và đối với các đối tượng Series
tương đương với việc sử dụng chỉ mục thông thường dựa trên []
. Mục đích của trình chỉ mục ix
sẽ trở nên rõ ràng hơn trong bối cảnh của các đối tượng DataFrame
, chúng ta sẽ thảo luận về chúng trong một khoảng thời gian ngắn.
Một nguyên tắc hướng dẫn viết mã Python là “rõ ràng hơn là ngầm định”.Tính rõ ràng của loc
và iloc
khiến chúng trở nên rất hữu ích trong việc duy trì mã sạch và dễ đọc; đặc biệt trong trường hợp chỉ số nguyên, tôi khuyến nghị sử dụng cả hai này để làm cho mã dễ đọc và hiểu, và ngăn chặn những lỗi tinh subtile do quy ước trộn lẫn chỉ mục/đoạn.
Sự lựa chọn dữ liệu trong DataFrame¶
Hãy nhớ rằng một DataFrame
hoạt động theo nhiều cách giống như một mảng hai chiều hoặc cấu trúc có cấu trúc, và theo các cách khác như một từ điển của các cấu trúc Series
chia sẻ cùng một chỉ mục.Những tương tự này có thể hữu ích khi chúng ta khám phá lựa chọn dữ liệu trong cấu trúc này.
DataFrame như là một từ điển¶
Đầu tiên, chúng ta sẽ xem xét tương tự đầu tiên là DataFrame
như là một từ điển của các đối tượng Series
liên quan.Hãy trở lại ví dụ của chúng ta về diện tích và dân số của các bang:
area = pd.Series({'California': 423967, 'Texas': 695662, 'New York': 141297, 'Florida': 170312, 'Illinois': 149995})pop = pd.Series({'California': 38332521, 'Texas': 26448193, 'New York': 19651127, 'Florida': 19552860, 'Illinois': 12882135})data = pd.DataFrame({'area':area, 'pop':pop})data
Các Series
riêng lẻ tạo thành các cột của DataFrame
có thể được truy cập thông qua chỉ mục kiểu từ điển của tên cột:
data['area']
California 423967Florida 170312Illinois 149995New York 141297Texas 695662Name: area, dtype: int64
Tương đương, chúng ta có thể sử dụng truy cập theo thuộc tính với tên cột là chuỗi:
data.area
California 423967Florida 170312Illinois 149995New York 141297Texas 695662Name: area, dtype: int64
Phương thức truy cập cột theo thuộc tính này thực ra truy cập vào chính đối tượng giống như phương thức truy cập cột theo từ điển:
data.area is data['area']
True
Mặc dù đây là một biểu trưng ngắn gọn hữu ích, hãy nhớ rằng nó không hoạt động cho tất cả các trường hợp!
Ví dụ, nếu tên cột không phải là chuỗi, hoặc nếu tên cột xung đột với các phương thức của DataFrame
, truy cập theo phong cách thuộc tính này không thể thực hiện.
Ví dụ, DataFrame
có một phương thức pop()
, vì vậy data.pop
sẽ chỉ đến phương thức này chứ không phải cột "pop"
:
data.pop is data['pop']
False
Đặc biệt, bạn nên tránh cám dỗ thử gán cột thông qua thuộc tính (tức là sử dụng data['pop'] = z
thay vì data.pop = z
).
Tương tự như với đối tượng Series
được thảo luận trước đó, cú pháp theo kiểu từ điển này cũng có thể được sử dụng để sửa đổi đối tượng, trong trường hợp này là thêm một cột mới:
data['density'] = data['pop'] / data['area']data
Đoạn mã này cho thấy một bản xem trước về cú pháp đơn giản của phép tính từng phần tử giữa các đối tượng Series
; chúng tôi sẽ khám phá sâu hơn về điều này trong phần Các phép toán trên dữ liệu trong Pandas.
DataFrame như một mảng hai chiều
Như đã đề cập trước đó, chúng ta cũng có thể xem DataFrame
như một mảng hai chiều nâng cao. Chúng ta có thể kiểm tra mảng dữ liệu cơ sở bằng cách sử dụng thuộc tính values
:
data.values
array([[ 4.23967000e+05, 3.83325210e+07, 9.04139261e+01], [ 1.70312000e+05, 1.95528600e+07, 1.14806121e+02], [ 1.49995000e+05, 1.28821350e+07, 8.58837628e+01], [ 1.41297000e+05, 1.96511270e+07, 1.39076746e+02], [ 6.95662000e+05, 2.64481930e+07, 3.80187404e+01]])
Với hình ảnh này trong tư duy, nhiều quan sát tương tự như mảng có thể được thực hiện trên chính DataFrame
.
data.T
Khi nói đến việc chỉ mục các đối tượng DataFrame
, tuy nhiên, rõ ràng việc chỉ mục theo kiểu từ điển của các cột không cho phép chúng ta đơn giản là xử lý nó như một mảng NumPy.Đặc biệt, việc truyền một chỉ mục duy nhất vào một mảng truy cập một hàng:
data.values[0]
array([ 4.23967000e+05, 3.83325210e+07, 9.04139261e+01])
và việc truyền một “index” duy nhất vào một DataFrame
để truy cập một cột:
data['area']
California 423967Florida 170312Illinois 149995New York 141297Texas 695662Name: area, dtype: int64
Do đó, để thực hiện chỉ mục theo kiểu mảng, chúng ta cần một quy ước khác.Ở đây, Pandas sử dụng lại các bộ chỉ mục loc
, iloc
và ix
đã được đề cập trước đó.Sử dụng bộ chỉ mục iloc
, chúng ta có thể chỉ mục mảng gốc như thể nó là một mảng NumPy đơn giản (sử dụng chỉ mục kiểu ngầm định của Python), nhưng các nhãn chỉ mục và cột của DataFrame
được duy trì trong kết quả:
data.iloc[:3, :2]
Tương tự, sử dụng chỉ số loc
chúng ta có thể chỉ mục dữ liệu gốc trong một kiểu dữ liệu giống như mảng nhưng sử dụng chỉ mục và tên cột rõ ràng:
data.loc[:'Illinois', :'pop']
Mục đánh chỉ mục ix
cho phép một sự kết hợp của hai phương pháp này:
data.ix[:3, :'pop']
Hãy nhớ rằng đối với các chỉ số số nguyên, trình chỉ mục ix
cũng có thể gây nhầm lẫn như đã thảo luận với các đối tượng Series
được chỉ số số nguyên.
Bất kỳ mẫu truy cập dữ liệu trong phong cách NumPy nào cũng có thể được sử dụng trong những trình chỉ mục này.Ví dụ, trong bộ chỉ mục loc
chúng ta có thể kết hợp lọc và chỉ mục phức tạp như sau:
data.loc[data.density > 100, ['pop', 'density']]
Bất kỳ trong số những quy ước chỉ mục này cũng có thể được sử dụng để đặt hoặc thay đổi các giá trị; điều này được thực hiện theo cách tiêu chuẩn mà bạn có thể quen thuộc từ việc làm việc với NumPy:
data.iloc[0, 2] = 90data
Để nâng cao khả năng xử lý dữ liệu trong Pandas, tôi đề nghị bạn dành một ít thời gian với một DataFrame
đơn giản và khám phá các loại chỉ số, cắt, lọc và chỉ số tinh vi mà các phương pháp chỉ số này cho phép.
Các nguyên tắc chỉ mục bổ sung¶
Có một số quy ước về chỉ mục bổ sung có thể có vẻ mâu thuẫn với phần thảo luận trước đó, nhưng vẫn có thể rất hữu ích trong thực tế.Trước hết, trong khi indexing đề cập đến các cột, thì slicing đề cập đến các hàng:
data['Florida':'Illinois']
Những lát cắt cũng có thể tham chiếu đến các hàng bằng số thay vì bằng chỉ số:
data[1:3]
Tương tự, các hoạt động che khuất trực tiếp cũng được hiểu theo từng hàng chứ không phải từng cột:
data[data.density > 100]
Hai quy ước này cú pháp tương tự như trên một mảng NumPy, và mặc dù chúng có thể không chính xác phù hợp với các quy ước của Pandas, nhưng trong thực tế chúng vẫn rất hữu ích.