Làm việc với CSV
1. Giới thiệu
Phần tiêu đề “1. Giới thiệu”CSV (Comma-Separated Values) là định dạng file văn bản dùng để lưu trữ dữ liệu dạng bảng. Mỗi dòng trong file là một hàng dữ liệu, các giá trị được ngăn cách bởi dấu phẩy.
Tại sao học CSV?
Phần tiêu đề “Tại sao học CSV?”- ✅ Định dạng phổ biến để trao đổi dữ liệu
- ✅ Dễ đọc bằng mắt thường
- ✅ Mở được bằng Excel, Google Sheets
- ✅ Thư viện csv của Python rất dễ sử dụng
Ví dụ file CSV
Phần tiêu đề “Ví dụ file CSV”name,age,cityAlice,25,New YorkBob,30,Los AngelesCharlie,22,Chicago2. Module csv
Phần tiêu đề “2. Module csv”Python có module csv built-in để làm việc với file CSV.
import csv3. Đọc File CSV
Phần tiêu đề “3. Đọc File CSV”3.1 - Đọc CSV với csv.reader()
Phần tiêu đề “3.1 - Đọc CSV với csv.reader()”import csv
# Mở và đọc file CSVwith open('data.csv', 'r', encoding='utf-8') as file: csv_reader = csv.reader(file)
# Đọc từng dòng for row in csv_reader: print(row)Output:
['name', 'age', 'city']['Alice', '25', 'New York']['Bob', '30', 'Los Angeles']['Charlie', '22', 'Chicago']3.2 - Bỏ qua header (dòng tiêu đề)
Phần tiêu đề “3.2 - Bỏ qua header (dòng tiêu đề)”import csv
with open('data.csv', 'r', encoding='utf-8') as file: csv_reader = csv.reader(file)
# Bỏ qua dòng đầu tiên next(csv_reader)
for row in csv_reader: name, age, city = row print(f"{name} is {age} years old and lives in {city}")Output:
Alice is 25 years old and lives in New YorkBob is 30 years old and lives in Los AngelesCharlie is 22 years old and lives in Chicago3.3 - Đọc CSV thành list
Phần tiêu đề “3.3 - Đọc CSV thành list”import csv
with open('data.csv', 'r', encoding='utf-8') as file: csv_reader = csv.reader(file) data = list(csv_reader)
print(data)# [['name', 'age', 'city'], ['Alice', '25', 'New York'], ...]4. Đọc CSV với DictReader
Phần tiêu đề “4. Đọc CSV với DictReader”DictReader đọc mỗi dòng thành dictionary với key là tên cột.
import csv
with open('data.csv', 'r', encoding='utf-8') as file: csv_reader = csv.DictReader(file)
for row in csv_reader: print(row) print(f"Name: {row['name']}, Age: {row['age']}")Output:
{'name': 'Alice', 'age': '25', 'city': 'New York'}Name: Alice, Age: 25{'name': 'Bob', 'age': '30', 'city': 'Los Angeles'}Name: Bob, Age: 30...Ưu điểm của DictReader
Phần tiêu đề “Ưu điểm của DictReader”- ✅ Truy cập dữ liệu bằng tên cột
- ✅ Code dễ đọc và bảo trì
- ✅ Tự động xử lý header
5. Ghi File CSV
Phần tiêu đề “5. Ghi File CSV”5.1 - Ghi CSV với csv.writer()
Phần tiêu đề “5.1 - Ghi CSV với csv.writer()”import csv
# Dữ liệu cần ghidata = [ ['name', 'age', 'city'], ['Alice', 25, 'New York'], ['Bob', 30, 'Los Angeles'], ['Charlie', 22, 'Chicago']]
# Ghi vào filewith open('output.csv', 'w', newline='', encoding='utf-8') as file: csv_writer = csv.writer(file)
# Ghi từng dòng for row in data: csv_writer.writerow(row)5.2 - Ghi nhiều dòng cùng lúc
Phần tiêu đề “5.2 - Ghi nhiều dòng cùng lúc”import csv
data = [ ['name', 'age', 'city'], ['Alice', 25, 'New York'], ['Bob', 30, 'Los Angeles']]
with open('output.csv', 'w', newline='', encoding='utf-8') as file: csv_writer = csv.writer(file) csv_writer.writerows(data) # writerows với s5.3 - Ghi CSV với delimiter khác
Phần tiêu đề “5.3 - Ghi CSV với delimiter khác”import csv
data = [ ['name', 'age', 'city'], ['Alice', 25, 'New York']]
# Dùng tab thay vì commawith open('output.tsv', 'w', newline='', encoding='utf-8') as file: csv_writer = csv.writer(file, delimiter='\t') csv_writer.writerows(data)6. Ghi CSV với DictWriter
Phần tiêu đề “6. Ghi CSV với DictWriter”import csv
# Dữ liệu dạng dictionarydata = [ {'name': 'Alice', 'age': 25, 'city': 'New York'}, {'name': 'Bob', 'age': 30, 'city': 'Los Angeles'}, {'name': 'Charlie', 'age': 22, 'city': 'Chicago'}]
# Ghi vào filewith open('output.csv', 'w', newline='', encoding='utf-8') as file: fieldnames = ['name', 'age', 'city'] csv_writer = csv.DictWriter(file, fieldnames=fieldnames)
# Ghi header csv_writer.writeheader()
# Ghi dữ liệu for row in data: csv_writer.writerow(row)7. Thêm dữ liệu vào CSV (Append)
Phần tiêu đề “7. Thêm dữ liệu vào CSV (Append)”import csv
# Dữ liệu mớinew_data = [ ['David', 28, 'Boston'], ['Emily', 26, 'Seattle']]
# Thêm vào cuối filewith open('data.csv', 'a', newline='', encoding='utf-8') as file: csv_writer = csv.writer(file) csv_writer.writerows(new_data)8. Xử lý delimiter và quotechar
Phần tiêu đề “8. Xử lý delimiter và quotechar”8.1 - Custom delimiter
Phần tiêu đề “8.1 - Custom delimiter”import csv
# File CSV dùng dấu chấm phẩywith open('data.csv', 'r', encoding='utf-8') as file: csv_reader = csv.reader(file, delimiter=';') for row in csv_reader: print(row)8.2 - Xử lý dấu ngoặc kép
Phần tiêu đề “8.2 - Xử lý dấu ngoặc kép”import csv
data = [ ['name', 'quote'], ['Alice', 'She said "Hello"'], ['Bob', 'He likes "Python"']]
with open('quotes.csv', 'w', newline='', encoding='utf-8') as file: csv_writer = csv.writer(file, quoting=csv.QUOTE_MINIMAL) csv_writer.writerows(data)9. Ví dụ thực tế
Phần tiêu đề “9. Ví dụ thực tế”Ví dụ 1: Đọc và xử lý dữ liệu điểm số
Phần tiêu đề “Ví dụ 1: Đọc và xử lý dữ liệu điểm số”import csv
# Đọc file điểm học sinhwith open('scores.csv', 'r', encoding='utf-8') as file: csv_reader = csv.DictReader(file)
for student in csv_reader: name = student['name'] math = int(student['math']) english = int(student['english']) average = (math + english) / 2
print(f"{name}: Trung bình = {average:.1f}")Ví dụ 2: Lọc và ghi dữ liệu
Phần tiêu đề “Ví dụ 2: Lọc và ghi dữ liệu”import csv
# Đọc dữ liệu và lọcwith open('employees.csv', 'r', encoding='utf-8') as infile: csv_reader = csv.DictReader(infile)
# Lọc nhân viên có tuổi > 30 filtered_data = [row for row in csv_reader if int(row['age']) > 30]
# Ghi dữ liệu đã lọcwith open('senior_employees.csv', 'w', newline='', encoding='utf-8') as outfile: fieldnames = ['name', 'age', 'department'] csv_writer = csv.DictWriter(outfile, fieldnames=fieldnames)
csv_writer.writeheader() csv_writer.writerows(filtered_data)Ví dụ 3: Đếm và thống kê
Phần tiêu đề “Ví dụ 3: Đếm và thống kê”import csvfrom collections import Counter
# Đếm số người theo thành phốwith open('data.csv', 'r', encoding='utf-8') as file: csv_reader = csv.DictReader(file)
cities = [row['city'] for row in csv_reader] city_counts = Counter(cities)
print("Thống kê theo thành phố:") for city, count in city_counts.items(): print(f"{city}: {count} người")10. Lỗi thường gặp
Phần tiêu đề “10. Lỗi thường gặp”Lỗi 1: Quên newline=‘’
Phần tiêu đề “Lỗi 1: Quên newline=‘’”# ❌ SAI - Có thể tạo dòng trốngwith open('data.csv', 'w') as file: csv_writer = csv.writer(file)
# ✅ ĐÚNGwith open('data.csv', 'w', newline='') as file: csv_writer = csv.writer(file)Lỗi 2: Quên encoding
Phần tiêu đề “Lỗi 2: Quên encoding”# ❌ SAI - Lỗi với ký tự tiếng Việtwith open('data.csv', 'r') as file: csv_reader = csv.reader(file)
# ✅ ĐÚNGwith open('data.csv', 'r', encoding='utf-8') as file: csv_reader = csv.reader(file)Lỗi 3: Không đóng file
Phần tiêu đề “Lỗi 3: Không đóng file”# ❌ SAIfile = open('data.csv', 'r')csv_reader = csv.reader(file)# Quên file.close()
# ✅ ĐÚNG - Dùng withwith open('data.csv', 'r') as file: csv_reader = csv.reader(file) # Tự động đóng file11. Tips và Best Practices
Phần tiêu đề “11. Tips và Best Practices”1. Luôn dùng context manager (with)
Phần tiêu đề “1. Luôn dùng context manager (with)”# ✅ TỐTwith open('data.csv', 'r', encoding='utf-8') as file: csv_reader = csv.reader(file) # Code của bạn2. Xác định encoding
Phần tiêu đề “2. Xác định encoding”# Với ký tự tiếng Việtwith open('data.csv', 'r', encoding='utf-8') as file: # Code của bạn3. Dùng DictReader/DictWriter cho code dễ đọc
Phần tiêu đề “3. Dùng DictReader/DictWriter cho code dễ đọc”# ✅ TỐT - Dễ hiểuwith open('data.csv', 'r') as file: reader = csv.DictReader(file) for row in reader: print(row['name']) # Rõ ràng4. Xử lý exception
Phần tiêu đề “4. Xử lý exception”try: with open('data.csv', 'r', encoding='utf-8') as file: csv_reader = csv.reader(file) for row in csv_reader: process(row)except FileNotFoundError: print("File không tồn tại!")except csv.Error as e: print(f"Lỗi CSV: {e}")12. So sánh reader vs DictReader
Phần tiêu đề “12. So sánh reader vs DictReader”| Feature | csv.reader | csv.DictReader |
|---|---|---|
| Kiểu dữ liệu trả về | List | Dictionary |
| Truy cập dữ liệu | Theo index: row[0] | Theo key: row[‘name’] |
| Xử lý header | Thủ công | Tự động |
| Tốc độ | Nhanh hơn một chút | Chậm hơn một chút |
| Dễ đọc | Ít hơn | Nhiều hơn |
Khuyến nghị: Dùng DictReader/DictWriter cho hầu hết trường hợp vì code dễ đọc và bảo trì.
📝 Bài tập thực hành
Phần tiêu đề “📝 Bài tập thực hành”Sau khi học xong bài này, hãy thực hành với các bài tập sau: