Chuỗi đối tượng Pandas¶
Một Pandas Series
là một mảng một chiều gồm dữ liệu được đánh chỉ mục.Nó có thể được tạo từ một danh sách hoặc mảng như sau:
data = pd.Series([0.25, 0.5, 0.75, 1.0])data
0 0.251 0.502 0.753 1.00dtype: float64
Nhìn vào kết quả, ta thấy Series
bao gồm cả một chuỗi các giá trị và một chuỗi các chỉ số, mà chúng ta có thể truy cập bằng các thuộc tính values
và index
.Các values
chỉ đơn giản là một mảng NumPy quen thuộc:
data.values
array([ 0.25, 0.5 , 0.75, 1. ])
Cái index
là một đối tượng giống như một mảng của kiểu pd.Index
, chúng ta sẽ thảo luận chi tiết hơn về nó sau.
data.index
RangeIndex(start=0, stop=4, step=1)
Tương tự như với một mảng NumPy, dữ liệu có thể được truy cập thông qua chỉ số liên quan bằng cú pháp dấu ngoặc vuông Python quen thuộc:
data[1]
0.5
data[1:3]
1 0.502 0.75dtype: float64
Như chúng ta sẽ thấy, Series
của Pandas được coi là phổ biến và linh hoạt hơn rất nhiều so với mảng một chiều của NumPy mà nó mô phỏng.
Series
như một mảng tổng quát hóa của NumPy¶
Cho đến thời điểm hiện tại, có vẻ như đối tượng Series
có thể thay thế hoàn toàn mảng một chiều của NumPy.Sự khác biệt cơ bản là sự hiện diện của chỉ số: trong khi Mảng Numpy có một chỉ số nguyên được xác định một cách ngầm định để truy cập vào các giá trị, đối tượng Series
của Pandas có một chỉ số được xác định rõ ràng liên kết với các giá trị.
Định nghĩa chỉ số rõ ràng này mang đến cho đối tượng Series
các tính năng bổ sung. Ví dụ, chỉ số không nhất thiết phải là một số nguyên, mà có thể bao gồm các giá trị của bất kỳ loại nào mà chúng ta mong muốn.Ví dụ, nếu chúng ta muốn, chúng ta có thể sử dụng chuỗi làm chỉ số:
data = 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
Và việc truy cập các mục hoạt động như dự kiến:
data['b']
0.5
Chúng ta có thể sử dụng cả các chỉ mục không liên tục hoặc không tuần tự:
data = pd.Series([0.25, 0.5, 0.75, 1.0], index=[2, 5, 3, 7])data
2 0.255 0.503 0.757 1.00dtype: float64
data[5]
0.5
Series như một từ điển chuyên ngành¶
Bằng cách này, bạn có thể coi một Series
trong Pandas một chút giống như một từ điển Python chuyên biệt.Một từ điển là một cấu trúc mà phân ánh các khóa tùy ý tới một tập các giá trị tùy ý, và một Series
là một cấu trúc mà ánh xạ các khóa có kiểu tới một tập các giá trị có kiểu.Kiểu này là quan trọng: giống như mã nguồn được biên dịch cụ thể cho một mảng NumPy giúp tăng hiệu suất so với một danh sách Python cho một số phép toán nhất định, thông tin kiểu dữ liệu của một Series
Pandas giúp nó hiệu quả hơn rất nhiều so với từ điển Python cho một số phép toán nhất định.
Để giải thích một cách rõ ràng hơn về sự tương đương giữa Series
và từ điển, chúng ta có thể tạo trực tiếp một đối tượng Series
từ một từ điển Python:
population_dict = {'California': 38332521, 'Texas': 26448193, 'New York': 19651127, 'Florida': 19552860, 'Illinois': 12882135}population = pd.Series(population_dict)population
California 38332521Florida 19552860Illinois 12882135New York 19651127Texas 26448193dtype: int64
Mặc định, một Series
sẽ được tạo ra, trong đó chỉ mục được lấy từ các khóa đã được sắp xếp.Từ đây, có thể thực hiện truy cập các mục theo kiểu từ điển thông thường:
population['California']
38332521
Khác với một từ điển, Series
cũng hỗ trợ các hoạt động kiểu mảng như cắt:
population['California':'Illinois']
California 38332521Florida 19552860Illinois 12882135dtype: int64
Chúng ta sẽ thảo luận về một số điểm kỳ quặc của việc chỉ mục và cắt mảng trong Pandas trong Index và Lựa Chọn Dữ Liệu.
Xây dựng đối tượng Series¶
Chúng ta đã thấy một vài cách để xây dựng một Series
trong Pandas từ đầu; tất cả các cách đó đều là một phiên bản của sau đây:
>>> pd.Series(data, index=index)
trong đó index
là một đối số tùy chọn, và data
có thể là một trong nhiều thực thể.
Ví dụ, data
có thể là một danh sách hoặc một mảng NumPy, trong trường hợp này index
mặc định là một chuỗi số nguyên:
pd.Series([2, 4, 6])
0 21 42 6dtype: int64
dữ liệu
có thể là một số thuộc loại scalar, nó được lặp lại để điền vào chỉ số được chỉ định:
pd.Series(5, index=[100, 200, 300])
100 5200 5300 5dtype: int64
data
có thể là một từ điển, trong đó index
mặc định là các khóa của từ điển đã được sắp xếp:
pd.Series({2:'a', 1:'b', 3:'c'})
1 b2 a3 cdtype: object
Trong mỗi trường hợp, chỉ số có thể được thiết lập một cách rõ ràng nếu kết quả khác được ưa thích:
pd.Series({2:'a', 1:'b', 3:'c'}, index=[3, 2])
3 c2 adtype: object
Lưu ý rằng trong trường hợp này, Series
chỉ được điền dữ liệu thông qua các khóa được xác định rõ ràng.
Đối tượng DataFrame trong Pandas¶
Cấu trúc cơ bản tiếp theo trong Pandas là DataFrame
.Giống như đối tượng Series
được thảo luận trong phần trước, DataFrame
có thể được coi là một sự tổng quát hóa của một mảng NumPy hoặc là một sự đặc biệt hóa của từ điển Python.Bây giờ chúng ta sẽ xem xét từng quan điểm này.
DataFrame như một mảng NumPy tổng quát¶
Nếu một Series
tương đương với một mảng một chiều với các chỉ mục linh hoạt, một DataFrame
tương đương với một mảng hai chiều với cả chỉ mục hàng linh hoạt và tên cột linh hoạt.Giống như bạn có thể nghĩ về một mảng hai chiều là một chuỗi được sắp xếp của các cột một chiều, bạn có thể nghĩ về một DataFrame
như một chuỗi của các đối tượng Series
được sắp xếp.Ở đây, “được sắp xếp” có nghĩa là chúng có chia sẻ cùng một chỉ mục.
Để minh họa điều này, hãy trước tiên xây dựng một Series
mới liệt kê diện tích của mỗi trong năm tiểu bang được thảo luận ở phần trước:
area_dict = {'California': 423967, 'Texas': 695662, 'New York': 141297, 'Florida': 170312, 'Illinois': 149995}area = pd.Series(area_dict)area
California 423967Florida 170312Illinois 149995New York 141297Texas 695662dtype: int64
Bây giờ chúng ta đã có điều này cùng với Series population
từ trước đó, chúng ta có thể sử dụng một từ điển để xây dựng một đối tượng hai chiều duy nhất chứa thông tin này:
states = pd.DataFrame({'population': population, 'area': area})states
Giống như đối tượng Series
, DataFrame
có một thuộc tính index
để truy cập các nhãn chỉ mục:
states.index
Index(['California', 'Florida', 'Illinois', 'New York', 'Texas'], dtype='object')
Thêm vào đó, DataFrame
có một thuộc tính là columns
, đây là một đối tượng Index
chứa các nhãn cột:
states.columns
Index(['area', 'population'], dtype='object')
Do đó, DataFrame
có thể được coi là sự tổng quát hóa của một mảng NumPy hai chiều, trong đó cả hàng và cột đều có một chỉ mục tổng quát để truy cập vào dữ liệu.
Số chia lợi dụng bằng từ Điển đặc biệt¶
Tương tự, chúng ta cũng có thể coi DataFrame
như một loại đặc biệt của từ điển.Trong khi từ điển ánh xạ một khóa tới một giá trị, DataFrame
ánh xạ một tên cột tới một Series
chứa dữ liệu cột.Ví dụ, yêu cầu thuộc tính 'area'
sẽ trả về đối tượng Series
chứa các diện tích mà chúng ta đã thấy trước đây:
states['area']
California 423967Florida 170312Illinois 149995New York 141297Texas 695662Name: area, dtype: int64
Lưu ý điểm nghẽn tiềm năng ở đây: trong một mảng NumPy hai chiều, data[0]
sẽ trả về dòng đầu tiên. Đối với một DataFrame
, data['col0']
sẽ trả về cột đầu tiên.Vì lý do này, có lẽ tốt hơn là coi DataFrame
như những từ điển tổng quát hơn là những mảng tổng quát, mặc dù cả hai cách nhìn vào tình huống đều có ích.Chúng ta sẽ khám phá các phương pháp linh hoạt hơn để lập chỉ mục DataFrame
trong Data Indexing and Selection.
Tạo đối tượng DataFrame
Một Bảng dữ liệu
Pandas có thể được xây dựng theo nhiều cách khác nhau.Ở đây chúng ta sẽ cung cấp một số ví dụ.
Từ một đối tượng Series đơn lẻ¶
Một DataFrame
là một tập hợp các đối tượng Series
, và một DataFrame
với một cột có thể được tạo từ một Series
duy nhất:
pd.DataFrame(population, columns=['population'])
Từ một danh sách của các từ điển¶
Mọi danh sách từ điển có thể được chuyển thành một DataFrame
.Chúng tôi sẽ sử dụng một biểu đạt danh sách đơn giản để tạo dữ liệu:
data = [{'a': i, 'b': 2 * i} for i in range(3)]pd.DataFrame(data)
Ngay cả khi một số khóa trong từ điển bị thiếu, Pandas sẽ điền vào chúng bằng giá trị NaN
(tức là “không phải là số”):
pd.DataFrame([{'a': 1, 'b': 2}, {'b': 3, 'c': 4}])
Từ một từ điển các đối tượng Series
Như chúng ta đã thấy trước đây, một DataFrame
có thể được tạo từ một từ điển các đối tượng Series
:
pd.DataFrame({'population': population, 'area': area})
Từ một mảng NumPy hai chiều
Cho một mảng hai chiều dữ liệu, chúng ta có thể tạo ra một DataFrame
với bất kỳ tên cột và chỉ mục nào.
pd.DataFrame(np.random.rand(3, 2), columns=['foo', 'bar'], index=['a', 'b', 'c'])
Từ một mảng có cấu trúc NumPy
Chúng ta đã bàn về mảng có cấu trúc trong Dữ liệu có cấu trúc: Mảng có cấu trúc của NumPy.Một DataFrame
trong Pandas hoạt động tương tự như một mảng có cấu trúc và có thể được tạo trực tiếp từ một mảng có cấu trúc:
A = np.zeros(3, dtype=[('A', 'i8'), ('B', 'f8')])A
array([(0, 0.0), (0, 0.0), (0, 0.0)], dtype=[('A', '<i8'), ('B', '<f8')])
pd.DataFrame(A)
Đối tượng Chỉ số của Pandas¶
Chúng ta đã thấy ở đây cả đối tượng Series
và DataFrame
đều chứa một chỉ số rõ ràng cho phép bạn tham chiếu và thay đổi dữ liệu.Đối tượng Index
này là một cấu trúc thú vị trong chính nó, và nó có thể được coi như một mảng không thay đổi hoặc như một tập hợp có thứ tự (kỹ thuật là một multi-set, vì đối tượng Index
có thể chứa các giá trị lặp lại).Những quan điểm đó có một số kết quả thú vị trong các phép toán có sẵn trên các đối tượng Index
.Ví dụ đơn giản, hãy tạo một Index
từ một danh sách số nguyên:
ind = pd.Index([2, 3, 5, 7, 11])ind
Int64Index([2, 3, 5, 7, 11], dtype='int64')
Index như một mảng không thay đổi¶
Các Index
trong nhiều trường hợp hoạt động giống như một mảng. Ví dụ, chúng ta có thể sử dụng cú pháp truy cập thông thường của Python để lấy giá trị hoặc lát cắt:
ind[1]
3
ind[::2]
Int64Index([2, 5, 11], dtype='int64')
Đối tượng Index
cũng có nhiều thuộc tính quen thuộc từ mảng NumPy:
print(ind.size, ind.shape, ind.ndim, ind.dtype)
5 (5,) 1 int64
Một khác biệt giữa các đối tượng Index
và mảng NumPy là các chỉ số không thể thay đổi – tức là, chúng không thể được sửa đổi thông qua các phương pháp bình thường:
ind[1] = 0
---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-34-40e631c82e8a> in <module>()----> 1 ind[1] = 0/Users/jakevdp/anaconda/lib/python3.5/site-packages/pandas/indexes/base.py in __setitem__(self, key, value) 1243 1244 def __setitem__(self, key, value):-> 1245 raise TypeError("Index does not support mutable operations") 1246 1247 def __getitem__(self, key):TypeError: Index does not support mutable operations
Khả năng không thay đổi này giúp việc chia sẻ các chỉ số giữa nhiều DataFrame
và mảng trở nên an toàn hơn, mà không bị các tác động phụ từ việc sửa đổi không cố ý các chỉ số.
Chỉ mục như một tập hợp được sắp xếp¶
Đối tượng Pandas được thiết kế để cung cấp hỗ trợ cho các thao tác như kết hợp dữ liệu giữa các bộ dữ liệu, phụ thuộc vào nhiều khía cạnh của toán học tập hợp.Đối tượng Index
tuân thủ nhiều quy ước được sử dụng bởi cấu trúc dữ liệu set
tích hợp sẵn của Python, để ta có thể tính toán các phép hợp, giao, hiệu và các phép kết hợp khác một cách quen thuộc:
indA = pd.Index([1, 3, 5, 7, 9])indB = pd.Index([2, 3, 5, 7, 11])
indA & indB # intersection
Int64Index([3, 5, 7], dtype='int64')
indA | indB # union
Int64Index([1, 2, 3, 5, 7, 9, 11], dtype='int64')
indA ^ indB # symmetric difference
Int64Index([1, 2, 9, 11], dtype='int64')
Các hoạt động này cũng có thể được truy cập qua các phương thức của đối tượng, ví dụ như indA.intersection(indB)
.