[Data Analytics] Bí quyết sử dụng hàm merge trong Pandas: Tip Hay và lưu ý

Hàm merge trong Pandas cách sử dụng hiệu quả và tip hay
18 Phút Đọc

Khi làm việc với dữ liệu trong Pandas, bạn sẽ thường gộp nhiều bảng dữ liệu khác khác nhau lại với nhau. Trong Pandas, hàm merge cho phép bạn làm điều đó từ hai DataFrame dựa trên một hoặc nhiều cột khoá chung, nó giống phép ‘JOIN’ trong SQL. Trong bài viết này mình sẽ hướng dẫn cách sử dụng hàm merge một cách hiệu quả, các tip và những điều cần lưu ý khi sử dụng. Bắt đầu nào!

Cơ bản về hàm merge

Hàm merge trong Pandas cơ bản giống phép ‘JOIN’ trong SQL, cú pháp như sau:

pd.merge(
    left,
    right,
    how='inner',
    on = None,
    left_on = None,
    right_on = None,
    left_index = False,
    right_index = False,
    sort = False,
    suffixes = ('_x', '_y'),
    copy = True,
    indicator = False,
    validate = None
)

Giải thích các tham số trong hàm merge

  • left và right: Hai DataFrame cần kết hợp.
  • how: Loại phép gộp (‘inner’, ‘outer’, ‘left’, ‘right’).
  • on: Cột hoặc danh sách cột để kết hợp giữa hai DataFrame.
  • left_on và right_on: Các cột tương ứng để kết hợp nếu hai DataFrame có tên cột khác nhau.
  • left_index và right_index: Sử dụng chỉ mục để kết hợp.
  • suffixes: Hậu tố thêm vào khi có cột trùng tên giữa hai DataFrame.
  • indicator: Thêm cột chỉ ra nguồn của mỗi bản ghi (‘both’, ‘left_only’, ‘right_only’).

Ví dụ minh hoạ

Giả sử bạn có 2 DataFrame df1, df2

DataFrame 1 (df1): có 2 cột dữ liệu id và name

import pandas as pd

data1 = {
    "id": [1, 2, 3],
    "name": ["Alice", "Bob", "Charlie"]
}
df1 = pd.DataFrame(data1)

DataFrame 2 (df2): có 2 cột dữ liệu id và age

data2 = {
    "id": [2, 3, 4],
    "age": [25, 30, 35]
}
df2 = pd.DataFrame(data2)

Nội dung của df1 và df2

# df1
   id     name
0   1    Alice
1   2      Bob
2   3  Charlie

# df2
   id  age
0   2   25
1   3   30
2   4   35

Cách sử dụng hàm merge

Chúng ta sẽ bắt đầu tìm hiểu các cách join khác nhau nhé

1. Phép ‘inner join’

Gộp hai bảng lại với nhau dựa trên các giá trị chung của cột id.

result_inner = pd.merge(df1, df2, on="id", how="inner") print(result_inner)

Kết quả

   id     name  age
0   2      Bob   25
1   3  Charlie   30

Inner join dựa trên giá trị chung của cột id trong hai DataFrame. Ở đây, cả hai DataFrame đều có chứa id 2 và 3, vì thế kết quả là sự kết hợp dữ liệu từ cả hai DataFrame dựa trên các id 2 và 3.

2. Phép ‘left join’

Khách với ‘inner join’, ‘left join’ sẽ giữ lại tất cả dữ liệu từ df1 và kết hợp dữ liệu từ df2 dựa trên id.

Cú pháp hàm merge trong Pandas
result_left = pd.merge(df1, df2, on="id", how="left")
print(result_left)

Kết quả ‘left join’ giữ lại tất cả dữ liệu ở df1 và kết hợp với dữ liệu từ df2 dựa trên giá trị chung của cột id. Trong trường hợp này, df1 và df2 đều có id 2 và 3, nên chỉ có id 2 và 3 từ df2 được giữ lại.

   id     name   age
0   1    Alice   NaN
1   2      Bob  25.0
2   3  Charlie  30.0

Và một điều lưu ý, hãy quay lại dữ liệu ở df1 và df2:

  • df1: có 2 cột dữ liệu là ‘id’ và ‘name’
  • df2: có 2 cột dữ liệu là ‘id’ và ‘age’

Bạn để ý kết quả sau khi merge, hai id 2 và 3 đều xuất hiện ở hai bảng, nên dữ liệu được kết hợp để cung cấp đầy đủ thông tin id, name, và age. Tuy nhiên, id 1 chỉ có ở df1, nên trong kết quả chỉ chứa id và name, còn cột age được gán là NaN (Not a Number) biểu diễn dữ liệu trống trong Pandas.

3. Phép ‘right join’

Phép ‘right join’ ngược lại với ‘left join’ chỉ giữ lại dữ liệu DataFrame df2 bên phải và kết hợp dữ liệu df1 ở cột dữ liệu chung là ‘id’

result_right = pd.merge(df1, df2, on="id", how="right")
print(result_right)

Kết quả

   id     name  age
0   2      Bob   25
1   3  Charlie   30
2   4      NaN   35

Bạn để ý ở đây dữ liệu của 2 id 2 và 3 đều xuất hiện ở cả hai df1 và df2 nên dữ liệu sẽ được kết hợp lại và có đầy đủ thông tin id, name, age. Tuy nhiên id 4 chỉ có ở df2, nên trong kết quả chỉ chứa id và age, còn cột name được gán là NaN.

4. Phép ‘outer join’

Với ‘outer join’ tất cả dữ liệu từ cả hai DataFrame được giữ lại và gộp dựa trên id.

result_outer = pd.merge(df1, df2, on="id", how="outer")
print(result_outer)

Kết quả

   id     name   age
0   1    Alice   NaN
1   2      Bob  25.0
2   3  Charlie  30.0
3   4      NaN  35.0

Tất cả dữ liệu sẽ được giữ lại ở cả hai DataFrame, với những id xuất hiện ở cả hai DataFrame sẽ được kết hợp đầy đủ thông tin id, name, và age. Và những id chỉ xuất hiện ở 1 DataFrame sẽ được gán NaN cho các cột dữ liệu thiếu.

Một số điểm cần lưu ý khi sử dụng hàm merge trong Pandas

1. Kiểm tra dữ liệu trước khi kết hợp

Trùng lặp giá trị trong cột khóa:

  • Đảm bảo cột khóa (on, left_on, right_on) không có dữ liệu trùng lặp nếu bạn mong muốn kết hợp dữ liệu độc nhất.
  • Sử dụng .drop_duplicates() hoặc .unique() để kiểm tra và loại bỏ các giá trị trùng lặp.
import pandas as pd

# Tạo hai DataFrame
df1 = pd.DataFrame({'id': [1, 2, 2, 3], 'name': ['Alice', 'Bob', 'Bob', 'Charlie']})
df2 = pd.DataFrame({'id': [2, 3, 4, 4], 'age': [25, 30, 40, 40]})

# Kiểm tra dữ liệu trùng lặp
if df1.duplicated(['id']).any() or df2.duplicated(['id']).any():
    print("Có dữ liệu trùng lặp trong cột khóa")
else:
    print("Không có dữ liệu trùng lặp trong cột khóa")
  • duplicated(): Kiểm tra xem có giá trị nào trùng lặp trong cột được chỉ định hay không.
  • any(): Trả về True nếu có bất kỳ giá trị trùng lặp nào.

2. Xử lý dữ liệu thiếu (NaN)

  • Dữ liệu kết hợp có thể chứa giá trị NaN, đặc biệt khi sử dụng how=’left’, how=’right’ hoặc how=’outer’.
  • Kiểm tra và xử lý các giá trị thiếu (NaN) bằng cách dùng .fillna() hoặc .dropna().
# Tạo hai DataFrame
df1 = pd.DataFrame({'id': [1, 2, 3], 'name': ['Alice', 'Bob', 'Charlie']})
df2 = pd.DataFrame({'id': [2, 3, 4], 'age': [25, 30, 40]})

# Kết hợp hai DataFrame bằng outer join
df_merged = pd.merge(df1, df2, on='id', how='outer')

# Điền giá trị mặc định cho các giá trị thiếu
df_merged.fillna({'age': 0, 'name': 'Unknown'}, inplace=True)

print(df_merged)

# Kết quả
   id     name  age
0   1   Alice  0.0
1   2     Bob  25.0
2   3 Charlie  30.0
3   4 Unknown  40.0
  • pd.merge(): Kết hợp hai DataFrame dựa trên cột id với phương thức outer để giữ lại tất cả dữ liệu từ cả hai DataFrame.
  • fillna(): Điền giá trị mặc định cho các giá trị thiếu (NaN):
    • age: Điền giá trị ‘0’.
    • name: Điền giá trị ‘Unknown’.
  • inplace=True: Áp dụng thay đổi trực tiếp trên DataFrame.

3. Hậu tố khi có cột trùng tên

Sử dụng tham số suffixes để đặt hậu tố phân biệt nếu hai DataFrame có các cột trùng tên.

import pandas as pd

# Tạo hai DataFrame với cột trùng tên
df1 = pd.DataFrame({'id': [1, 2, 3], 'name': ['Alice', 'Bob', 'Charlie'], 'value': [10, 20, 30]})
df2 = pd.DataFrame({'id': [2, 3, 4], 'name': ['Bobby', 'Charles', 'David'], 'value': [200, 300, 400]})

# Kết hợp hai DataFrame sử dụng inner join với hậu tố khác nhau
result = pd.merge(df1, df2, on='id', how='inner', suffixes=('_from_df1', '_from_df2'))

print(result)

# Kết quả
   id name_from_df1  value_from_df1 name_from_df2  value_from_df2
0   2           Bob              20         Bobby             200
1   3       Charlie              30       Charles             300

4. Kiểm tra sự tương thích của khóa kết hợp

Sử dụng tham số validate để đảm bảo đúng loại kết hợp như mong muốn (‘one_to_one’, ‘one_to_many’, ‘many_to_one’, ‘many_to_many’).

import pandas as pd

# Tạo hai DataFrame với cột khóa 'id'
df1 = pd.DataFrame({'id': [1, 2, 3], 'name': ['Alice', 'Bob', 'Charlie']})
df2 = pd.DataFrame({'id': [2, 3, 1], 'age': [25, 30, 22]})

# Kết hợp hai DataFrame với kiểm tra loại kết hợp một-một
try:
    result = pd.merge(df1, df2, on='id', how='inner', validate='one_to_one')
    print(result)
except pd.errors.MergeError as e:
    print("MergeError:", e)

Giải thích:

  • validate: Tham số này kiểm tra loại kết hợp dự kiến giữa hai DataFrame.
  • one_to_one: Xác nhận rằng mỗi giá trị trong cột khóa chỉ xuất hiện một lần ở cả hai DataFrame.
  • Nếu dữ liệu không thỏa mãn điều kiện one_to_one, sẽ có lỗi MergeError.

5. Chỉ định rõ các cột kết hợp

Đặc biệt khi các DataFrame có tên cột khác nhau, hãy sử dụng left_on và right_on.

import pandas as pd

# Tạo hai DataFrame
df1 = pd.DataFrame({'id1': [1, 2, 3], 'name': ['Alice', 'Bob', 'Charlie']})
df2 = pd.DataFrame({'id2': [2, 3, 4], 'age': [25, 30, 40]})

# Kết hợp hai DataFrame khi cột trong df1 là 'id1' và trong df2 là 'id2'
result = pd.merge(df1, df2, left_on='id1', right_on='id2', how='inner')

print(result)

# Kết quả
   id1     name  id2  age
0    2      Bob    2   25
1    3  Charlie    3   30

Giải thích:

  • left_on: Cột dùng để nối trong df1.
  • right_on: Cột dùng để nối trong df2.
  • how=’inner’: Chỉ giữ lại các hàng có giá trị chung giữa id1 và id2.

6. Sử dụng indicator để biết nguồn gốc của bản ghi

Thêm cột indicator để biết dữ liệu đến từ DataFrame nào.

import pandas as pd

# Tạo hai DataFrame
df1 = pd.DataFrame({'id': [1, 2, 3], 'name': ['Alice', 'Bob', 'Charlie']})
df2 = pd.DataFrame({'id': [2, 3, 4], 'age': [25, 30, 40]})

# Sử dụng indicator để xác định nguồn gốc của hàng
result = pd.merge(df1, df2, on='id', how='outer', indicator=True)

print(result)

# Kết quả
   id     name   age      _merge
0   1    Alice   NaN   left_only
1   2      Bob  25.0        both
2   3  Charlie  30.0        both
3   4      NaN  40.0  right_only

Giải thích:

  • indicator: Tham số này tạo thêm một cột mới trong kết quả, mặc định là ‘_merge’, để chỉ ra nguồn gốc của từng hàng dữ liệu:
    • left_only: Hàng chỉ có trong df1.
    • right_only: Hàng chỉ có trong df2.
    • both: Hàng xuất hiện ở cả hai DataFrame.

Lời khuyên nâng cao sau đây khi sử dụng hàm merge trong Pandas

Tối ưu hiệu suất với khóa có chỉ mục

Sử dụng chỉ mục (index) khi thực hiện merge để tối ưu hiệu suất. Thiết lập chỉ mục trên các cột khóa kết hợp trước khi sử dụng merge giúp tận dụng cấu trúc chỉ mục, tăng tốc độ truy xuất dữ liệu.

# Thiết lập chỉ mục trên cột khóa
df1.set_index('id', inplace=True)
df2.set_index('id', inplace=True)

# Sử dụng left_index và right_index để merge
result = pd.merge(df1, df2, left_index=True, right_index=True, how='inner')

Chỉ kết hợp các cột cần thiết

Nếu DataFrame có nhiều cột nhưng bạn chỉ cần một vài cột cho việc kết hợp, bạn chỉ nên chọn những cột cần thiết để tăng hiệu suất và giảm bộ nhớ sử dụng.

# Chỉ chọn các cột cần thiết từ mỗi DataFrame
result = pd.merge(df1[['id', 'name']], df2[['id', 'age']], on='id', how='inner')

Tránh kết hợp dữ liệu quá lớn không cần thiết

Nếu dữ liệu quá lớn, hãy chia nhỏ hoặc lọc trước khi kết hợp. Xem xét sử dụng chunksize hoặc query trước khi merge để tăng hiệu suất.

# Chia nhỏ DataFrame để kết hợp theo từng phần
chunks = pd.read_csv('large_dataset.csv', chunksize=10000)
result = pd.DataFrame()
for chunk in chunks:
    partial_result = pd.merge(chunk, df2, on='id', how='inner')
    result = pd.concat([result, partial_result])

Giải thích:

  • chunksize: Đọc file CSV theo từng phần, giúp xử lý tập dữ liệu lớn mà không cần tải toàn bộ vào bộ nhớ.
  • for chunk in chunks‘: Duyệt qua từng phần dữ liệu.
  • pd.merge(): Kết hợp dữ liệu từng phần với df2.
  • pd.concat(): Kết hợp các kết quả từng phần thành một DataFrame đầy đủ.

Tối ưu bộ nhớ với ‘Categorical’ dtypes

Khi cột kết hợp có nhiều giá trị lặp lại, sử dụng kiểu dữ liệu Categorical giúp tối ưu bộ nhớ.

# Chuyển cột 'id' thành kiểu dữ liệu Categorical
df1['id'] = df1['id'].astype('category')
df2['id'] = df2['id'].astype('category')

# Tiến hành merge
result = pd.merge(df1, df2, on='id', how='inner')

Sử dụng query hoặc eval để lọc dữ liệu kết hợp

Sử dụng query hoặc eval để thực hiện các phép lọc và tính toán nhanh hơn sau khi kết hợp.

# Sử dụng query để lọc dữ liệu sau khi merge
result = pd.merge(df1, df2, on='id', how='inner')
filtered_result = result.query('age > 25')

# Sử dụng eval để tính toán thêm các cột mới
result.eval('age_ratio = age / value1', inplace=True)
  • query: Lọc dữ liệu dựa trên biểu thức điều kiện.
  • eval: Thực hiện các phép tính toán nhanh và hiệu quả hơn, hỗ trợ thêm các cột mới.

Hy vọng với những chia sẽ trong nội dung bài viết này, bạn sẽ hiểu và sử dụng hiệu quả hàm merge trong phân tích dữ liệu trong Pandas.

Với vai trò một Performance Marketer, mình cũng rất hay sử dụng hàm này khi kết hợp dữ liệu từ nhiều bảng để phân tích hiệu quả và tối ưu quảng cáo Google Ads, Facebook Ads. Nhưng để có đủ dữ liệu để phân tích, trước tiên cần lên kế hoạch tracking đầy đủ những dữ liệu bạn cần.

Hãy đăng ký nhận thông tin mới để cập nhật những nội dung hữu ích:

  • Chiến lược triển khai tracking: Cách lên kế hoạch và thiết lập tracking dữ liệu phù hợp.
  • Thu thập dữ liệu tự động: Sử dụng APIs, Webhooks, và các công cụ khác để thu thập dữ liệu nhanh chóng và hiệu quả.
  • Phân tích data để có insight tối ưu quảng cáo.

Bạn có thể quan tâm:

Chia sẻ bài viết này
Theo dõi
Tôi tin rằng chìa khóa để thành công trong digital marketing nằm ở việc đưa ra quyết định dựa trên dữ liệu. Đó là lý do tại sao tôi đặc biệt quan tâm đến việc thiết lập theo dõi tracking và thu thập dữ liệu hiệu quả, để hiểu hành vi người dùng của từng nền tảng quảng cáo. Nó giúp tôi tự tin hơn trong việc tối ưu hóa các chiến dịch quảng cáo. Mỗi con số, mỗi phân tích đều giúp tôi tiến gần hơn đến mục tiêu cuối cùng: không chỉ đạt được kết quả, mà còn có khả năng mở rộng vượt trội.
Để lại một bình luận

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Exit mobile version