Những lỗi thường gặp khi sử dụng Pandas

By JoeVu, at: 22:31 Ngày 11 tháng 8 năm 2023

Thời gian đọc ước tính: __READING_TIME__ minutes

The common mistakes with Pandas
The common mistakes with Pandas

Pandas là một thư viện Python mạnh mẽ và linh hoạt cung cấp khả năng thao tác và phân tích dữ liệu. Tuy nhiên, giống như bất kỳ công cụ nào, nó cũng đi kèm với những cạm bẫy riêng mà các nhà phát triển junior thường mắc phải. Trong bài viết này, chúng ta sẽ khám phá một số lỗi thường gặp cần tránh khi làm việc với Pandas để đảm bảo quá trình xử lý dữ liệu mượt mà và hiệu quả hơn.

 

1. Hiểu nhầm DataFrame so với Series

 

Sự nhầm lẫn giữa DataFrame và Series khá phổ biến. DataFrame là cấu trúc dữ liệu hai chiều với các hàng và cột, trong khi Series là mảng một chiều được gắn nhãn (các cột của một DataFrame).

# Tạo một DataFrame và một Series
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Truy cập một cột dưới dạng Series
column_series = df['A']

# Truy cập một hàng dưới dạng Series (không chính xác)
# Điều này sẽ gây ra lỗi KeyError
row_series = df[0]


# Thay vào đó, chúng ta nên làm 
# Truy cập một hàng dưới dạng Series
row_series = df.loc[0] # Sử dụng nhãn chỉ mục

 

2. Cảnh báo SettingWithCopyWarning 

 

Sửa đổi một tập con của DataFrame mà không có gán rõ ràng có thể dẫn đến SettingWithCopyWarning. Điều này thường xảy ra khi cố gắng sửa đổi dữ liệu trong một lát cắt của DataFrame mà không sử dụng đúng .loc hoặc .iloc.

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Sửa đổi một tập con mà không có gán chính xác
subset = df[df['A'] > 1]
subset['B'] = 10  # Điều này có thể kích hoạt SettingWithCopyWarning

# Truy cập một hàng dưới dạng Series
row_series = df.loc[0] # Sử dụng nhãn chỉ mục

# Thay vào đó, chúng ta nên làm 

subset = df[df['A'] > 1]
subset.loc[:, 'B'] = 10 # Sử dụng .loc[] để tránh cảnh báo

 

3. Lồng chỉ mục

 

Việc lồng nhiều thao tác lập chỉ mục (df['column']['row']) không được khuyến khích vì nó có thể dẫn đến hành vi không thể đoán trước và lỗi.

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Lồng chỉ mục (không chính xác)
value = df['A']['B']  # Điều này có thể không hoạt động như mong đợi

# Thay vào đó, chúng ta nên làm 

value = df.loc['B', 'A']  # Sử dụng .loc[] cho nhãn hàng và cột

 

4. Không sử dụng .copy() khi cần thiết 

 

Khi tạo một DataFrame hoặc Series mới từ một DataFrame hoặc Series hiện có và sửa đổi nó, hãy chắc chắn sử dụng .copy() để tránh thay đổi không chủ ý đối với dữ liệu gốc.

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Sửa đổi bản sao mà không sử dụng .copy()
subset = df[df['A'] > 1]
subset['B'] = 10  # Điều này có thể ảnh hưởng đến DataFrame 'df' gốc

# Thay vào đó, chúng ta nên làm 
subset = df[df['A'] > 1].copy()
subset['B'] = 10

 

 

5. Xử lý giá trị thiếu

 

Không xử lý đúng các giá trị thiếu (NaN hoặc None) có thể dẫn đến lỗi trong tính toán và phân tích. Việc hiểu các phương pháp như dropna(), fillna()interpolate() là rất quan trọng.

# Tạo một DataFrame với các giá trị thiếu
import pandas as pd
import numpy as np

data = {'A': [1, np.nan, 3], 'B': [4, 5, np.nan]}
df = pd.DataFrame(data)

# Bỏ các hàng có giá trị thiếu
cleaned_df = df.dropna()

# Điền các giá trị thiếu bằng một giá trị cụ thể
filled_df = df.fillna(0)

 

6. Áp dụng hàm không chính xác

 

Áp dụng hàm cho DataFrame hoặc Series bằng apply() mà không hiểu mục đích và hành vi của nó có thể dẫn đến kết quả không mong muốn.

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Áp dụng hàm cho một Series (đúng)
square_root = df['A'].apply(lambda x: x ** 0.5)

# Áp dụng hàm cho toàn bộ DataFrame (không chính xác)
# Điều này sẽ gây ra lỗi
squared_df = df.apply(lambda x: x ** 2)

# Thay vào đó, chúng ta nên làm 

square_root = df['A'].apply(lambda x: x ** 0.5)
squared_df = df.apply(lambda x: x ** 2, axis=0)  # Áp dụng hàm cho các cột

 

7. Sử dụng iterrows()itertuples()

 

Các phương pháp này kém hiệu quả hơn đối với việc lặp lại trên DataFrame so với các phép toán vector hóa hoặc sử dụng hàm .apply().

 

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Sử dụng iterrows (kém hiệu quả)
for index, row in df.iterrows():
    print(row['A'], row['B'])

# Sử dụng itertuples (hiệu quả hơn)
for row in df.itertuples():
    print(row.A, row.B)

 

8. Không sử dụng phép toán vector hóa 

 

Pandas được tối ưu hóa cho các phép toán vector hóa. Thực hiện các phép tính từng phần tử bằng vòng lặp có thể chậm và không hiệu quả.

 

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Sử dụng vòng lặp for (kém hiệu quả)
squared_list = []
for value in df['A']:
    squared_list.append(value ** 2)

# Sử dụng phép toán vector hóa (hiệu quả hơn)
squared_array = df['A'] ** 2

 

9. Sử dụng sai GroupBy

 

Sử dụng hàm groupby() không chính xác có thể dẫn đến kết quả tổng hợp không chính xác. Ngoài ra, việc quên đặt lại chỉ mục sau khi nhóm có thể gây ra sự cố lập chỉ mục.

 

# Tạo một DataFrame
import pandas as pd

data = {'Category': ['A', 'B', 'A'], 'Value': [10, 20, 30]}
df = pd.DataFrame(data)

# Nhóm không chính xác
grouped = df.groupby('Category')
mean_values = grouped.mean()  # Điều này có thể đưa ra kết quả không mong muốn

# Nhóm chính xác
grouped = df.groupby('Category').sum()

 

10. Hiểu nhầm lập chỉ mục

 

Không hiểu cách đặt, đặt lại hoặc thao tác với chỉ mục có thể gây ra sự nhầm lẫn trong việc lựa chọn và hợp nhất dữ liệu.

 

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Đặt chỉ mục (đúng)
df.set_index('A', inplace=True)

# Đặt lại chỉ mục không chính xác
# Điều này sẽ tạo ra một cột chỉ mục bổ sung
df.reset_index(inplace=True)

 

11. Thao tác dữ liệu không hiệu quả

 

Các nhà phát triển junior có thể lạm dụng vòng lặp for để sửa đổi giá trị DataFrame, điều này thường kém hiệu quả hơn so với việc sử dụng các hàm tích hợp sẵn hoặc các phép toán vector hóa.

 

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Sử dụng vòng lặp for để sửa đổi (không hiệu quả)
for index, row in df.iterrows():
    df.at[index, 'B'] = row['B'] * 2

# Sử dụng phép toán vector hóa (hiệu quả)
df['B'] = df['B'] * 2

 

12. Trộn lẫn &| so với andor

 

Khi lọc DataFrame, việc sử dụng &| cho các phép toán boolean khác với việc sử dụng andor.

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Trộn lẫn toán tử (không chính xác)
subset = df[(df['A'] > 1) and (df['B'] > 4)]  # Điều này sẽ gây ra lỗi

# Sử dụng toán tử chính xác
subset = df[(df['A'] > 1) & (df['B'] > 4)]

 

13. Bỏ qua việc sử dụng bộ nhớ

 

DataFrame lớn có thể tiêu tốn rất nhiều bộ nhớ. Việc không lưu ý đến việc sử dụng bộ nhớ có thể dẫn đến sự cố hoặc chậm lại.

# Tạo một DataFrame lớn
import pandas as pd
import numpy as np

data = {'A': np.random.random(1000000)}
df = pd.DataFrame(data)

# Hiển thị việc sử dụng bộ nhớ
print(df.memory_usage(deep=True).sum())

 

14. Không đọc tài liệu

 

Pandas có tài liệu phong phú cung cấp các ví dụ và lời giải thích cho tất cả các hàm của nó. Việc không tham khảo tài liệu có thể dẫn đến sự nhầm lẫn và lỗi.

# Tạo một DataFrame
import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)

# Sử dụng hàm không chính xác
# Tham khảo tài liệu để sử dụng chính xác
df.replace(1, 10)

 

15. Mã chưa được tối ưu hóa

 

Viết mã lặp lại trên DataFrame lớn mà không tận dụng tối ưu hóa tích hợp sẵn của Pandas có thể dẫn đến hiệu suất chậm.

# Tạo một DataFrame lớn
import pandas as pd

data = {'A': range(100000)}
df = pd.DataFrame(data)

# Tính toán dựa trên vòng lặp không hiệu quả
result = []
for value in df['A']:
    result.append(value * 2)

# Tính toán vector hóa được tối ưu hóa
result = df['A'] * 2

 

16. Bỏ qua việc nối chuỗi phương thức

 

Pandas hỗ trợ nối chuỗi phương thức, trong đó nhiều thao tác được áp dụng theo trình tự. Việc bỏ qua thực hành này có thể dẫn đến mã ít dễ đọc và kém hiệu quả hơn.

# Không có nối chuỗi phương thức
subset = df[df['A'] > 1]
subset = subset.dropna()
subset['B'] = subset['B'] * 2

# Có nối chuỗi phương thức
subset = df[df['A'] > 1].dropna().assign(B=lambda x: x['B'] * 2)

 

17. Không kiểm tra kiểu dữ liệu

 

Pandas suy ra kiểu dữ liệu khi đọc dữ liệu, nhưng đôi khi nó có thể đoán sai. Việc không kiểm tra và sửa các kiểu dữ liệu có thể dẫn đến lỗi.

# Chuyển đổi kiểu dữ liệu không chính xác
df['A'] = df['A'].astype(str)  # Nếu 'A' chứa các giá trị không phải số

# Chuyển đổi kiểu dữ liệu chính xác
df['A'] = df['A'].astype(int)  # Đảm bảo 'A' chứa các số nguyên hợp lệ

 

 

Bằng việc nhận thức được những lỗi thường gặp này và thực hành thói quen lập trình tốt, các nhà phát triển junior có thể nâng cao khả năng sử dụng Pandas và giảm lỗi khi làm việc với dữ liệu. Việc làm quen với tài liệu của Pandas, tìm kiếm lời khuyên từ các nhà phát triển có kinh nghiệm và thực hành thường xuyên sẽ mở đường cho việc thao tác và phân tích dữ liệu hiệu quả và hiệu quả. 

Tag list:
- Mistake
- Tips
- Tips and Tricks
- python
- pandas
- common mistakes

Theo dõi

Theo dõi bản tin của chúng tôi và không bao giờ bỏ lỡ những tin tức mới nhất.