Data wrangling (Sắp xếp dữ liệu) là một thuật ngữ rộng được sử dụng, thường không chính thức, để mô tả quá trình chuyển đổi dữ liệu thô thành định dạng rõ ràng, có tổ chức, sẵn sàng để sử dụng. Đối với chúng ta, việc sắp xếp dữ liệu chỉ là một bước trong quá trình xử lý trước dữ liệu, nhưng đây là một bước quan trọng.
Trang 1CHƯƠNG 3: SẮP XẾP DỮ LIỆU
Giới thiệu
Data wrangling (Sắp xếp dữ liệu) là một thuật ngữ rộng
được sử dụng, thường không chính thức, để mô tả quá trìnhchuyển đổi dữ liệu thô thành định dạng rõ ràng, có tổ chức, sẵnsàng để sử dụng Đối với chúng ta, việc sắp xếp dữ liệu chỉ làmột bước trong quá trình xử lý trước dữ liệu, nhưng đây là mộtbước quan trọng
Cấu trúc dữ liệu phổ biến nhất được sử dụng để “sắp xếp”
dữ liệu là khung dữ liệu (Dataframe), có thể vừa trực quan vừacực kỳ linh hoạt Các khung dữ liệu có dạng bảng, nghĩa làchúng dựa trên các hàng và cột như bạn thấy trong bảng tính
Có hai điều quan trọng cần lưu ý trong khung dữ liệu:
- Đầu tiên, trong khung dữ liệu, mỗi hàng tương ứng với mộtquan sát (ví dụ: một hành khách) và mỗi cột tương ứng với mộtđặc điểm (giới tính, tuổi, v.v.)
- Thứ hai, mỗi cột chứa một tên (ví dụ: Tên, PClass, Tuổi) và mỗihàng chứa một số chỉ mục (ví dụ: 0 dành cho cô ElisabethWalton Allen) Chúng ta sẽ sử dụng những thông tin này để lựachọn và thao tác các quan sát và đặc điểm
Trong chương này, chúng tôi sẽ đề cập đến nhiều kỹ thuậtkhác nhau để thao tác khung dữ liệu bằng thư viện pandas vớimục tiêu tạo ra một tập hợp các quan sát có cấu trúc rõ ràng, rõràng để xử lý trước
Tạo một series của dataframe
Pandas Series là một container 1 chiều của Pandas (haycòn gọi là Python Iterable) tương tự như list là một container có
Trang 2sẵn của Python Nó chính là một loại dữ liệu tượng trưng chomỗi cột trong Dataframe Mỗi giá trị của series phải được lưu trữcùng loại data type Ví dụ chúng ta có một giá trị là 1 (interger)
và một giá trị là “orange” (string) trong cùng một series thìseries đó sẽ có data type là object dtype (hay là string trongPython)
Vì Dataframe được xem như là một dictionary các seriesobjects trong đó mỗi key chính là tên cột và value chính làseries, chúng ta có thể kết luận rằng series tương đương vớiPython list, ngoại trừ việc các giá trị của series phải cùng dtypetrong khi các giá trị của list có thể khác dtype Chúng ta cũngthấy rằng ndarray cũng sẽ có cấu trúc tương tự series
Các dễ nhất để tạo series chính là truyền một list Pythonvào methods series() của pandas Nếu chúng ta truyền một listgồm nhiều giá trị thuộc các dtype khác nhau thì pandas sẽ tựđộng chọn dtype phổ biến nhất trong list đó
Chúng ta thấy bên trái series chính là các hàng số, đóchính là index number của series Nó cũng tương tự như rowname và row index Do đó chúng ta có thể đặt tên cho rowindex
Trang 3Trong code cell trên chúng ta dùng parameter index để chỉđịnh row number o là person và row number 1 là Who Do đókhi kết quả trình bày Person cho wes Mckinney và Who trìnhbày cho Creatoe of pandas.
Khi sử dụng hàm print với series thì index sẽ được trìnhbày dưới dạng cột thứ nhất và các giá trị được trình bày ở cộtthứ hai
Nếu chúng ta chỉ muốn trình bày index của series thìchúng ta thêm atrribute index hoặc dùng method key
Nếu chúng ta chỉ muốn biết index đầu tiên của series thìchúng ta thêm [0] với attribute index và [0] với method key()
Trang 4Nếu chúng ta chỉ muốn trình bày giá trị của series thìchúng ta chỉ cần dùng methods values
Tính chất của một series định lượng (hay còn gọi là vector số)Nếu trường hợp chúng ta có hai vector có cùng độ dài thì chúng
ta có thể cộng từng hàng hai vector đó lại với nhau
Hoặc chúng ta nhân hai vector cùng độ dài lại với nhau
Trang 5Khi chúng ta áp dụng một phép toán lên vector với một con số,thì con số này sẽ được tái sử dụng cho tất cả các thành tố củavector
Nếu hai series định lượng có chiều dài không bằng nhau thìpandas sẽ cộng các hàng có cùng index ở hai series còn cáchàng không có giá trị sẽ được để giá trị missing kí hiệu là NaN
Trang 6Trong code trên series thứ hai chỉ có hai giá trị 1 và 100 tươngứng ở index number 0 và 1, do đó Python sẽ chỉ cộng age vàseries [1, 100] ở hai hàng có index 0 và 1 mà thôi.
Một đặc điểm hay nữa của Python chính là nó luôn thực hiện cácphép toán cho hai series dựa hoàn toàn vào index number, bất
kể cho dù chúng ta có đảo thứ tự của các hàng như thế nàochăng nữa Đó là do Python luôn luôn gắn một index numbermặc định cho một giá trị bất kì, do đó khi thay đổi thứ tự củaseries thì giá trị đó vẫn luôn có index đó
Giả sử ta có series age và series rev_ages nghĩa là series agesxếp từ cao đến thấp
Chúng ta nhận thấy index number của giá trị 37 vẫn là 0 cho dù
đã được sắp xếp lại thứ tự trong rev_ages
Khi cộng hai series này lại Python cũng tự động cộng các hàng
có trùng số index number
Trang 7Tạo một Dataframe
Tạo Dataframe từ Python dictionary
pandas có nhiều phương thức để tạo đối tượng DataFramemới Một phương pháp dễ dàng là khởi tạo DataFrame bằngdictionary của Python Trong từ điển, mỗi khóa là một tên cột vàgiá trị là một danh sách, trong đó mỗi mục tương ứng với mộthàng:
Trang 80 Jacky Jackson 38 True
1 Steven
Stevenson
25 False
Chúng ta cũng có thể dễ dàng thêm cột mới và Dataframe:
# Add a column for eye color
dataframe["Eyes"] = ["Brown", "Blue"]
ta sẽ được tạo từ dữ liệu thực mà chúng tôi đã tải từ các nguồnkhác (ví dụ: tệp CSV hoặc cơ sở dữ liệu)
Trang 9Khi tạo Dataframe chúng ta có thể thêm hai tham số làindex và columns Index columns sẽ giúp chúng ta quy định rowindex của Dataframe thay vì dùng row number mặc định củaPython Còn tham số columns giúp chúng ta quy định thứ tự củacác columns.
Trong code cell trên, chúng ta lấy cột name trước đó trởthành row index cho Dataframe Chúng ta cũng thiết lập thứ tựcác cột bằng colunns tham số
Tính chất của một Dataframe
Một Dataframe gồm 3 phần: index, column và values Để xem
ba thành phần này chúng ta dùng thuộc tính index, column vàvalues của Dataframe
Với thuộc tính index chúng ta thấy index của bộ Dataframe nàybắt đầu từ 0 và kết thúc ở 8, mỗi index cách nhau 1 đơn vị
Hoặc
Trang 10Với thuộc tính column chúng có thể xem được tên các cột trongdataframe
Thuộc tính values rất có ích khi chúng ta không muốn liệt kêcác index label mà chỉ muốn hiển thị các giá trị dưới dạng arraycủa numpy
Dataframe vì được cấu trúc từ series nên nó cũng có tính chấtbroadcasting nghĩa là chúng ta có thể thực hiện các phép toánvới toàn bộ Dataframe
Trong đoạn code trên chúng ta lấy Dataframe scientist nhâncho 2 thì chúng ta được kết quả là giá trị của các cột string sẽđược nhân lên hai còn giá trị của cột số sẽ được gấp đôi lên
Trang 11Tóm tắt dataframe
Kiểm tra lớp của dữ liệu
Khi dữ liệu tải vào Python có thể có nhiều lớp khác nhaunhư pandas dataframe, series, array v.v Để kiểm tra class của
dữ liệu chúng ta dùng hàm type có sẵn của Python (hàm nàyđược cài sẵn trong Python không phải từ các thư viện riêng nhưpandas)
Hàm type rất có ích khi bạn phải làm việc với nhiều đốitượng Python và bạn muốn biết đối tượng đó thuộc loại gì
Như vậy dữ liệu df ở trên thuộc loại pandas dataframe
Xem số hàng, số cột của dataframe
Mỗi dataframe của panda sẽ có thuộc tính shape nghĩa làcho chúng ta biết được số hàng và số dòng của nó
Thuộc tính shape của dataframe sẽ trả về một tuple trong
đó con số đầu tiên là số hàng và con số thứ hai là số cột
Xem tên các cột của Dataframe
Chúng ta sử dụng method columns để biết tên các cộttrong Dataframe
Trang 12Xem loại dữ liệu của các biến trong dataframe
Để biết loại dữ liệu của từng cột chúng ta có thể dùngthuộc tính dtypes hay dùng method info()
Trong pandas có các loại dữ liệu sau và tương ứng trongPython là các loại dữ liệu khác nhau
Xem 5 hàng đầu của dataframe
Trong trường hợp dataframe của chúng ta quá lớn chúng
ta không thể liệt kê toàn bộ các hàng của dataframe Chúng ta
Trang 13chỉ xem được một subset của nó mà thôi Method head() củadataframe cho phép chúng ta xem dữ liệu của 5 hàng đầu tiêncủa dataframe.
Xem 5 hàng cuối cùng của dataframe
Chúng ta dùng method tail() để xem 5 hàng cuối cùng củadataframe
Mô tả các số tập trung và phân tán của biến định lượng trong Dataframe
Chúng ta có thể tóm tắt các số thống kê của các biến địnhlượng trong Dataframe bằng cách dùng hàm describe:
# Show statistics
dataframe.describe()
Trang 14Mô tả min, max, mean, sum và count của một biến định lượngtrong Dataframe
Trang 15Mô tả count của tất cả các biến trong Dataframe
# Load data
dataframe = pd.read_csv(url)
Trang 16# Get the minimum of every column
# Mean Age, min and max SexCode
dataframe.agg({"Age":["mean"], "SexCode":["min", "max"]})
Trang 17url ='https://raw.githubusercontent.com/chrisalbon/sim_data/master/titanic.csv'
# Load data
dataframe = pd.read_csv(url)
# Select unique values
dataframe['Sex'].unique()
array(['female', 'male'], dtype=object)
Để đếm số giá trị của biến phân loại chúng ta dùng hàmnunique
# Show number of unique values
Name: Sex, dtype: int64
Mô tả tần suất cho hai biến phân loại trong Dataframe
# Number of people who survived and didn't survive in each class
dataframe.groupby(
["PClass","Survived"]).agg({"Survived":["count"]}
).reset_index()
Trang 18ss
Surviv ed
Cou nt
kỹ thuật tính năng Mặc dù biểu đồ trực quan cũng hữu íchnhưng việc có số liệu thống kê mô tả cụ thể như vậy làm tài liệutham khảo để hiểu rõ hơn về dữ liệu thường rất hữu ích
Mô tả biến định lượng theo biến phân loại trong Dataframe
Chúng ta có thể dùng lệnh groupby để tóm tắt biến địnhlượng theo biến định tính
# Load library
import pandas as pd
# Create URL
Trang 19url =
'https://raw.githubusercontent.com/chrisalbon/sim_data/master/titanic.csv'
SexCo de
1.0
male 31.0143
38
0.166863
0.0
groupby là nơi việc sắp xếp dữ liệu thực sự bắt đầu hìnhthành Điều rất phổ biến là có một DataFrame trong đó mỗihàng là một người hoặc một sự kiện và chúng ta muốn nhómchúng theo một số tiêu chí rồi tính toán một thống kê Ví dụ:bạn có thể tưởng tượng một DataFrame trong đó mỗi hàng làmột lần bán hàng riêng lẻ tại một chuỗi nhà hàng quốc gia vàchúng ta muốn tổng doanh số bán hàng của mỗi nhà hàng.Chúng ta có thể thực hiện điều này bằng cách nhóm các hàngtheo từng nhà hàng rồi tính tổng của từng nhóm
Người dùng mới sử dụng groupby thường viết một dòngnhư thế này và bối rối trước những gì được trả về:
# Group rows
Trang 20# Group rows, count rows
dataframe.groupby('Survived')['Name'].count()
Survived
0 863
1 450
Name: Name, dtype: int64
Lưu ý [Name] sau groupby? Đó là vì số liệu thống kê tómtắt cụ thể chỉ có ý nghĩa đối với một số loại dữ liệu nhất định Vídụ: trong khi việc tính độ tuổi trung bình theo giới tính là hợp lýthì việc tính tổng độ tuổi theo giới tính lại không hợp lý Trongtrường hợp này, chúng tôi nhóm dữ liệu thành sống sót haykhông, sau đó đếm số lượng tên (tức là hành khách) trong mỗinhóm
Chúng ta cũng có thể nhóm theo cột đầu tiên, sau đónhóm nhóm đó theo cột thứ hai:
# Group rows, calculate mean
dataframe.groupby(['Sex','Survived'])['Age'].mean()
Sex Survived
female 0 24.901408
Trang 211 30.867143
male 0 32.320780
1 25.951875
Name: Age, dtype: float64
Lọc dữ liệu trong dataframe
Lọc một cột bất kỳ trong dataframe
Chúng ta có thể chọn một cột bất kỳ trong dataframe bằng cách
sử dụng dấu ngoặc vuông
Nếu chúng ta dùng hàm type để kiểm tra lớp của cột này thìchúng ta thấy nó là series (hay còn gọi là vector) của dataframe
Tuy nhiên nếu chúng ta đưa cột vào một list thì khi đó chúng ta
sẽ chọn ra được một dataframe chứ không phải 1 series
Chúng ta thấy country được đặt trong dấu ngoặc vuông nghĩa làtrong single list, vì vậy Python sẽ tách cột đó trở thành mộtdataframe
Trang 22Có một cách khác là chúng ta dùng dấu chấm để chọn ra mộtcột như dưới đây
Tuy nhiên cách sử dụng dấu chấm này có hai bất lợi: nếu têncủa cột trùng với tên một thuộc tính nào đó ví dụ như shape thìkhi dùng dấu chấm sẽ không trả về giá trị cột đó mà là số hàng
và số cột của datagram Một hạn chế thứ hai là nếu tên cột cókhoảng trắng thì chúng ta không thể dùng phương pháp dấuchấm này
Lọc nhiều cột trong dataframe
Để có thể xem một số cột trong dataframe chúng ta cầnphải đặt các cột muốn xem vào một list trong dấu ngoặc vuôngbên trong Còn dấu ngoặc vuông bên ngoài là nói Python truyvấn cho chúng ta subset dữ liệu dựa trên các cột trong list Lưu
ý chúng ta chỉ dùng dấu ngoặc vuông với tên cột Còn nếumuốn dùng vị trí index của cột chúng ta phải dùng iloc[] chứkhông phải []
Trang 23Lọc một hàng trong dataframe
Lọc hàng đầu tiên của dataframe
Chúng ta có thể dùng thuộc tính accessor của panda
là .loc[] để lọc một hàng dựa trên index label của hàng đó.Index label chính là một nhãn mà chúng ta gán cho mỗi hàng
Chúng ta có thể dùng loc[] như sau
Chúng ta cũng có thể dùng iloc[] để lọc hàng đầu tiên.iloc[] chỉ khác với loc[] ở chỗ nó dùng index location nghĩa làindex number của hàng do pandas mặc định Pandas mặc định
số index của dòng đầu tiên là 0 và tiếp tục lên trên
Chúng ta cũng có thể dùng hàm head với n=1 để lọc hàngđầu tiên
Trang 24Tuy nhiên lưu ý khi dùng hàm head thì kết quả trả về sẽ làmột dataframe chứ không phải là một series.
Chúng ta có thể dùng iloc để lọc hàng cuối cùng Với iloc[]thì chúng ta có thể dùng -1 vì index number cho phép đi ngược
từ cuối lên trên với dấu – đằng trước
Trang 25Chúng ta cũng có thể dùng hàm tail với n=1 để lọc hàngcuối cùng
Tuy nhiên khi dùng tail chúng ta nhận thấy hàng trả về sẽ
là dataframe chứ không phải là series như khi dùng thuộc tínhloc[]
Lọc hàng bất kỳ
Để lọc hàng thứ 100 thì chúng ta phải dùng loc[99]
Tương tự như loc[] chúng ta cũng có thể dùng iloc[] trongtrường hợp này
Trang 26Lọc một hàng không bằng index label tùy chọn
Trong trường hợp chúng ta không muốn sử dụng indexlabel của Python, chúng ta có thể đặt index label cho Dataframebằng ngay chính giá trị một cột nào đó của Dataframe bằnghàm set_index
# Set index
dataframe = dataframe.set_index(dataframe['Name'])
Sau đó chúng ta có thể lọc một hàng bằng chính indexlabel đó
# Show row
dataframe.loc['Allen, Miss Elisabeth Walton']
Name Allen, Miss Elisabeth Walton
Trang 27Lọc nhiều hàng trong dataframe
Với iloc[] thì kết quả cũng tương tự
Lọc nhiều hàng kế tiếp nhau
Chúng ta có thể sử dụng dấu : để lọc các hàng liên tục từmột index này đến index khác:
# Select three rows
dataframe.iloc[1:4]
Name PClass Age Sex Survived SexCode
1 Allison, Miss Helen Loraine 1st 2.0 female 0 1
2 Allison, Mr Hudson Joshua Creighton 1st 30.0 male0
0
3 Allison, Mrs Hudson JC (Bessie Waldo Daniels) 1st 25.0
female 0 1
Trang 28Nếu chúng ta bỏ trống giá trị trước dấu : thì Python sẽ lọc
từ dòng đầu tiên đến dòng của giá trị sau dấu :
# Select four rows
dataframe.iloc[:4]
Name PClass Age Sex Survived SexCode
0 Allen, Miss Elisabeth Walton 1st 29.0 female 1 1
1 Allison, Miss Helen Loraine 1st 2.0 female 0 1
2 Allison, Mr Hudson Joshua Creighton 1st 30.0 male0
0
3 Allison, Mrs Hudson JC (Bessie Waldo Daniels) 1st 25.0
female 0 1
Lọc nhiều hàng, nhiều cột trong dataframe
Để lọc nhiều hàng nhiều cột trong dataframe chúng ta cóthể dùng loc[] hoặc iloc[] với cú pháp như sau
df.loc[[rows], [columns]]
hoặc
df.iloc[[rows], [columns]]
Sử dụng kỹ thuật list of interger cho hàng/cột
Đối với hàng chúng ta cần dùng kỹ thuật slicing trong Pythoncòn với cột chúng ta dùng list để chọn các cột
Trang 29Trong ví dụ trên ở trước dấu phẩy chúng ta dùng dấu : nghĩa làlấy tất cả các hàng, sau dấu phẩy chúng ta dùng list các cột làyear và pop.
Chúng ta cũng có thể dùng kỹ thuật tương tự cho iloc[] Chỉkhác một điều là khi chọn cột với iloc chúng ta có thể dùng dấu
âm cho cột
Trang 30Trong đoạn code trên chúng ta lọc hàng 42 và cột country bằng
cả iloc và loc
Trong đoạn code trên ở cả đối số hàng, chúng ta dùng một listcác hàng còn ở đối số cột chúng ta cũng dùng một list các cột.Nhìn chung đối với đối số hàng chúng ta nên sử dụng tên cột thìtốt hơn bởi vì nó giúp đoạn code dễ hiểu hơn Ngoài ra trongmột số trường hợp khi thứ tự cột bị đổi thì dùng index name củacột sẽ dẫn đến sai lầm
Trang 31Một lưu ý khác cần nhớ là khi dùng loc thì sẽ lọc theo đúng giátrị được đặt tên còn iloc sẽ giúp lọc hàng theo vị trị của hàng.
Sử dụng kỹ thuật range cho hàng/cột
Trong trường hợp khi bộ dữ liệu quá lớn gồm rất nhiềuhàng và cột thì việc liệt kê từng cột, hàng để lọc là điều khôngkhả thi Khi đó chúng ta có thể dùng một kỹ thuật là sử dụnghàm range Hàm range trong Python sẽ giúp tạo ra một dãy sốgiống như list với số bắt đầu và số kết thúc thì nó sẽ tạo ra các
số giữa hai số đó và bỏ đi số đầu và số cuối Sau đó chúng ta sẽdùng range này để lọc các cột hoặc hàng
Trang 32Trong cell code trên chúng ta thấy đầu tiên chúng ta tạo dãy số
có range là 5 số bắt đầu từ 0 đến 4 (bỏ số 5) Sau đó chúng tadùng chính range này để lọc ra các cột tương ứng với iloc là 0-4trong dataframe
Với code cell trên lần này chúng ta tạo range bắt đầu từ 3 vàkết thúc ở 5 vì 6 bị loại khỏi rang Sau đó áp dụng vào iloc thì sẽlọc cột 3, 4, 5 của dataframe
Trang 33Trong code cell trên lần này range của chúng ta bắt đầu từ 0kết thúc ở 5 nhưng cách 2 đơn vị, do đó sẽ tạo ra list số là 0, 2,
4 Như vậy chúng ta sẽ lọc được cột 0,2,4
Sử dụng kỹ thuật slicing
Việc chuyển một dãy số thành list nghe có vẻ kỳ lạ Do đóPython có một phương pháp khác hay hơn là sử dụng kỹ thuậtslicing (trượt dữ liệu) Trong slicing các giá trị cách nhau bởi dấu: chứ không phải dấu , như trong phương pháp range
Trang 34Trong code shell trên chúng ta dùng :3 để chỉ lấy 3 cột đầutiên của dataframe.
Trong code shell trên chúng ta lấy cột từ cột 3 đến cột 5
Với đoạn code trên chúng ta sẽ lấy cột từ 0-5 khoảng cách 2đơn vị Như vậy chúng ta sẽ lấy cột 0, 2, và cột 4
Trang 35Trong các đoạn code trên chúng ta có thể để trống giá trị đầu,giá trị cuối hay giá trị khoảng cách đều được Nếu để trống giátrị đầu thì Python vẫn biết là bắt đầu từ cột 0 Nếu để trống giátrị cuối thì Python vẫn sẽ biết là kết thúc ở cột cuối cùng Nếu
để trống giá trị khoảng cách thì Python mặc định khoảng cách
là 1
Thậm chí chúng ta có thể để trống cột thì Python cũng biết
là chúng ta chọn tất cả các cột
Trong code trên chúng ta chọn 4 hàng đầu làm first-half và
4 hàng sau làm second half Chúng ta không cần dùng dấu phẩy
để chọn cột vì mặc định chúng ta lấy tất cả các cột
Chúng ta cũng có thể lọc các cột có vị trí bất kỳ bằng kỹthuật slicing
Trang 36Trong đoạn code trên chúng ta lấy 5 hàng đầu, và các cột 0, 1,
Giả sử chúng ta có một series là Age, và chúng ta muốnlọc những hàng dữ liệu có age > age trung bình của series.Chúng ta cần viết câu lệnh sau
Tương tự như lọc series chúng ta cũng có thể dùng kỹthuật boolean masking để lọc cả Dataframe
Trong câu lệnh code trên chúng ta dùng hàm loc để lọc dữliệu theo cột Age > trung bình của cột Age
Một ví dụ khác là chúng ta muốn lọc tên của các đối tượng
có mức lương < 6000 đola
Trang 37Lọc Dataframe dựa trên điều kiện của một series định tính
Giả sử ta có bộ dữ liệu anscombe như sau
Biến dataset là biến định tính gồm 3 giá trị là I, II, III.Chúng ta muốn tách dataset thành dataset I, II, III thì chúng talàm như sau
Trang 38Lọc Dataframe dựa trên hai hay nhiều điều kiện
Trong thực tế chúng ta có thể phải lọc dữ liệu với nhiềuđiều kiện cùng lúc Giả sử chúng ta muốn lọc các record có mứclương <= 10000 dollar và có city là Sanzeno
Ví dụ 2 là chúng ta muốn lọc các record có mức lương <=
5000 dollar hoặc có city là Sanzeno
Sắp xếp giá trị
Chúng ta có thể sắp xếp Dataframe theo giá trị của mộtcột nào đó
# Load library