Chương 6 Tính toán trên các phần tử trong Pandas
6.1 Sử dụng Vectorization
Giả sử như muốn tạo cột price
= Item_Outlet_Sales
* 5%
Item_Outlet_Sales price
0 3735.1380 186.75690
1 443.4228 22.17114
2 2097.2700 104.86350
3 732.3800 36.61900
4 994.7052 49.73526
... ... ...
8518 2778.3834 138.91917
8519 549.2850 27.46425
8520 1193.1136 59.65568
8521 1845.5976 92.27988
8522 765.6700 38.28350
Nối hai cột lại với nhau, Ví dụ
nối
Item_type
vàItem_Fat_Content
thànhItem_Type_Fat_Content
nối
Outlet_Identifier
vàOutlet_Establishment_Year
thànhOutlet_Identifier_Establishment_Year
. Trong trường hợp hợp nàyOutlet_Establishment_Year
thuộc dạng số nên để nối dạng text và số ta ép kiểu dạng số về text sử dụngastype()
df['Item_Type_Fat_Content'] = df['Item_Type'] + '_' + df['Item_Fat_Content']
df['Outlet_Identifier_Establishment_Year'] = df['Outlet_Identifier'] + '_' +df['Outlet_Establishment_Year'].astype('str')
df[['Item_Type_Fat_Content', 'Outlet_Identifier_Establishment_Year']]
Item_Type_Fat_Content Outlet_Identifier_Establishment_Year
0 Dairy_Low Fat OUT049_1999
1 Soft Drinks_Regular OUT018_2009
2 Meat_Low Fat OUT049_1999
3 Fruits and Vegetables_Regular OUT010_1998
4 Household_Low Fat OUT013_1987
... ... ...
8518 Snack Foods_Low Fat OUT013_1987
8519 Baking Goods_Regular OUT045_2002
8520 Health and Hygiene_Low Fat OUT035_2004
8521 Snack Foods_Regular OUT018_2009
8522 Soft Drinks_Low Fat OUT046_1997
6.2 Sử dụng apply
Phương thức apply
để thực thi một hàm theo dòng hoặc cột
6.2.1 Sử dụng apply lên Series
Trong đó:
func
: là hàm cần thực thiconvert_dtype
: Giá trị kiểu boolean. Nếu nó được đặt thành True (mặc định), xử lý dữ liệu sẽ cố gắng tìm dtype tốt hơn cho các kết quả của hàmfunc
. NếuFalse
, thì dtype sẽ là type(object)args
: Các đối số của hàm
Ví dụ, thao tác Item_Outlet_Sales
* 5%
Sử dụng lambda function
0 186.75690
1 22.17114
2 104.86350
3 36.61900
4 49.73526
...
8518 138.91917
8519 27.46425
8520 59.65568
8521 92.27988
8522 38.28350
Name: Item_Outlet_Sales, Length: 8523, dtype: float64
Sử dụng hàm tự định nghĩa
0 186.75690
1 22.17114
2 104.86350
3 36.61900
4 49.73526
...
8518 138.91917
8519 27.46425
8520 59.65568
8521 92.27988
8522 38.28350
Name: Item_Outlet_Sales, Length: 8523, dtype: float64
Có thể truyền tham số k
vào hàm set_price
bằng hai cách
6.2.2 Sử dụng apply lên DataFrame
Ta dùng cú pháp
Trong đó:
func
: là hàm cần thực thiaxis
: thực thi theo dòng0
hoặc cột1
raw
: Xác định xem dòng hoặc cột có thể chuyển vềSeries
hoặcndarray
result_type
: Chỉ áp dụng choaxis=1
args
: Các đối số của hàm
Ví dụ:
sample_df = sample_df = pd.DataFrame([[1, 2, 'A'], [3, 6, 'B'], [5, 10, 'C']], columns=['A', 'B', 'C'])
sample_df
A B C
0 1 2 A
1 3 6 B
2 5 10 C
Áp dụng trên toàn DataFrame
A B C
0 2 4 AA
1 6 12 BB
2 10 20 CC
Lưu ý:
Khi áp dụng cho toàn DataFrame
hãy cẩn thận hàm func
truyền vào, nếu func
không áp dụng được cho toàn bộ các phần tử sẽ báo lỗi.
C
dạng str
, nhưng khi thay bằng x ** 2 sẽ báo lỗi vì toán tử **
không áp dụng cho str
Áp dụng trên một số cột trong DataFrame
0 13
1 13
2 13
dtype: int64
A 12
B 27
dtype: int64
Một cách khác áp dụng trên một số cột trong DataFrame
Sử dụng lambda
0 5
1 15
2 25
dtype: int64
Dùng hàm định nghĩa
0 5
1 15
2 25
dtype: int64
Mẹo:
Không nhất thiết giá trị trả về của hàm là giá trị đơn, giá trị trả về có thể dưới dạng list, tuple hoặc dict
Dùng
result_type
để thay đổi cách trả về
Ví dụ ta có 1 hàm trả về nhiều giá trị cùng lúc như sau
0 [5, -3]
1 [15, -9]
2 [25, -15]
dtype: object
Kết quả trả về của phương pháp trên là Series
với các giá trị của nó là dạng list. Để chuyển Series
này thành DataFrame
với các cột chứa các giá trị của list theo thứ tự, ta dùng result_type='expand'
0 1
0 5 -3
1 15 -9
2 25 -15
DataFrame
cho ví dụ trên mà không cần dùng result_type
bằng cách sử dụng pd.Series
của một dictionary
. Lúc này các cột của DataFrame
sẽ được đánh nhãn theo key của dictionary
X Y
0 5 -3
1 15 -9
2 25 -15
6.3 Sử dụng iterator
df = pd.read_csv('data/big_mart_sales.csv', usecols=['Item_Identifier', 'Item_Fat_Content', 'Item_Type', 'Outlet_Size', 'Item_Outlet_Sales', 'Outlet_Establishment_Year'])
6.3.1 Iterrows
(0,
Item_Identifier FDA15
Item_Fat_Content Low Fat
Item_Type Dairy
Outlet_Establishment_Year 1999
Outlet_Size Medium
Item_Outlet_Sales 3735.138
Name: 0, dtype: object)
Kết quả trả về cho row là 1 tuple gồm index và Series chứa các giá trị tại index đó.
Cách dùng vòng lặp trong iterrows
Để duyệt từng dòng ta dùng for
như bình thường
prices = []
for i, row in df.iterrows():
prices.append(row['Item_Outlet_Sales'] * 0.5)
print(prices[:5])
[1867.569, 221.7114, 1048.635, 366.19, 497.3526]
6.3.2 Itertuple
Trong đó:
index
:True
trả về kết quả kèm theo index vàFalse
lược bỏ indexname
: Quy định kiểu trả vềPandas
: trả về namedtupleNone
: trả về tuplenamedtuple
: trả về namedtuple
Trả về namedtuple
Pandas(Index=0, Item_Identifier='FDA15', Item_Fat_Content='Low Fat', Item_Type='Dairy', Outlet_Establishment_Year=1999, Outlet_Size='Medium', Item_Outlet_Sales=3735.138)
Trả về tuple
('FDA15', 'Low Fat', 'Dairy', 1999, 'Medium', 3735.138)
Cách dùng vòng lặp trong itertuples
name=default
prices = []
for row in df.itertuples():
prices.append(row.Item_Outlet_Sales * 0.5)
print(prices[:5])
name=None
6.4 So sánh các phương pháp lặp
def vectorizer(df):
prices = df['Item_Outlet_Sales'] * 0.5
def applyer(df):
prices = df['Item_Outlet_Sales'].apply(lambda x: x * 0.5)
def iterrows(df):
prices = []
for i, row in df.iterrows():
prices.append(row['Item_Outlet_Sales'] * 0.5)
def itertuples1(df):
prices = []
for row in df.itertuples():
prices.append(row.Item_Outlet_Sales * 0.5)
def itertuples2(df):
prices = []
for row in df.itertuples(index=False, name=None):
prices.append(row[5] * 0.5)
80.1 µs ± 42.8 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
1.37 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
256 ms ± 2.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
6.61 ms ± 200 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
3.91 ms ± 132 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
6.5 Xử lý song song trong pandas
Xử lý song song là phương pháp tận dụng số lượng core của CPU để giải quyết vấn đề trong thời gian ngắn hơn.