Python中處理CSV文件的核心方法詳解
1. 模塊簡介
CSV(Comma-Separated Values,逗號(hào)分隔值)是一種常見的文件格式,用于存儲(chǔ)表格數(shù)據(jù)。它使用逗號(hào)作為字段分隔符,每行代表一條記錄。
Python的csv模塊提供了專門用于處理CSV文件的功能,使得讀取和寫入CSV文件變得簡單高效。
主要功能包括:
- 讀取CSV文件內(nèi)容
- 寫入數(shù)據(jù)到CSV文件
- 處理帶標(biāo)題行的CSV文件
- 使用字典形式讀寫CSV數(shù)據(jù)
- 自定義分隔符和引用符
- 處理CSV中的特殊情況
2. 核心功能詳解
2.1 基本CSV讀取
使用csv.reader對象可以逐行讀取CSV文件內(nèi)容。
基本用法:
import csv
# 讀取CSV文件
with open('employees.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
for row_num, row in enumerate(reader, 1):
print(f"第{row_num}行: {row}")
注意事項(xiàng):
- 使用
with語句確保文件正確關(guān)閉 - 指定
encoding='utf-8'以正確處理中文字符 csv.reader返回的是一個(gè)迭代器,每次迭代返回一行數(shù)據(jù),作為列表
2.2 CSV寫入操作
使用csv.writer對象可以將數(shù)據(jù)寫入CSV文件。
基本用法:
import csv
# 準(zhǔn)備數(shù)據(jù)
sample_data = [
['姓名', '年齡', '城市', '職業(yè)'],
['張三', '25', '北京', '工程師'],
['李四', '30', '上海', '設(shè)計(jì)師'],
['王五', '28', '廣州', '產(chǎn)品經(jīng)理']
]
# 寫入CSV文件
with open('employees.csv', 'w', newline='', encoding='utf-8') as file:
writer = csv.writer(file)
writer.writerows(sample_data)
print("已創(chuàng)建示例CSV文件 'employees.csv'")
注意事項(xiàng):
- 使用
'w'模式創(chuàng)建新文件或覆蓋現(xiàn)有文件 - 設(shè)置
newline=''以避免額外的空行 writerows()方法可以一次寫入多行數(shù)據(jù)writerow()方法用于寫入單行數(shù)據(jù)
2.3 使用DictReader處理帶標(biāo)題的CSV
csv.DictReader可以將CSV文件的第一行作為字段名,返回的每行數(shù)據(jù)是一個(gè)字典,鍵為字段名,值為對應(yīng)的數(shù)據(jù)。
基本用法:
import csv
with open('employees.csv', 'r', encoding='utf-8') as file:
dict_reader = csv.DictReader(file)
for row_num, row in enumerate(dict_reader, 1):
print(f"員工{row_num}:")
for key, value in row.items():
print(f" {key}: {value}")
print()
優(yōu)勢:
- 可以通過字段名訪問數(shù)據(jù),而不是通過索引
- 代碼更具可讀性,尤其是當(dāng)CSV文件字段較多時(shí)
- 字段順序變化時(shí)代碼仍然可以正常工作
2.4 使用DictWriter寫入數(shù)據(jù)
csv.DictWriter可以將字典數(shù)據(jù)寫入CSV文件,需要指定字段名。
基本用法:
import csv
# 準(zhǔn)備字段名稱和數(shù)據(jù)
fieldnames = ['姓名', '年齡', '城市', '職業(yè)']
new_employee = {
'姓名': '周九',
'年齡': '29',
'城市': '武漢',
'職業(yè)': '前端開發(fā)'
}
# 追加新員工數(shù)據(jù)
with open('employees.csv', 'a', newline='', encoding='utf-8') as file:
dict_writer = csv.DictWriter(file, fieldnames=fieldnames)
dict_writer.writerow(new_employee)
print("已使用DictWriter添加新員工")
注意事項(xiàng):
- 必須指定
fieldnames參數(shù),定義字段的順序 - 字典中的鍵必須與
fieldnames中的字段名匹配 - 如果字典中缺少某些字段,會(huì)寫入空值
2.5 自定義分隔符和引用符
CSV文件不一定使用逗號(hào)作為分隔符,csv模塊支持自定義分隔符和引用符。
基本用法:
import csv
# 創(chuàng)建使用分號(hào)分隔的CSV文件
custom_data = [
['產(chǎn)品名稱', '價(jià)格', '庫存'],
['蘋果', '5.5', '100'],
['香蕉', '3.2', '200'],
['橙子', '4.8', '150']
]
with open('products.csv', 'w', newline='', encoding='utf-8') as file:
writer = csv.writer(file, delimiter=';', quoting=csv.QUOTE_MINIMAL)
writer.writerows(custom_data)
print("已創(chuàng)建使用分號(hào)分隔的CSV文件 'products.csv'")
# 讀取自定義分隔符的CSV文件
with open('products.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file, delimiter=';')
for row_num, row in enumerate(reader, 1):
print(f"第{row_num}行: {row}")
常用引用模式:
csv.QUOTE_MINIMAL:只在必要時(shí)使用引號(hào)csv.QUOTE_ALL:對所有字段使用引號(hào)csv.QUOTE_NONNUMERIC:對非數(shù)字字段使用引號(hào)csv.QUOTE_NONE:不使用引號(hào)
2.6 處理CSV中的特殊情況
CSV文件中可能包含特殊字符,如引號(hào)、逗號(hào)、換行符等,csv模塊可以正確處理這些情況。
基本用法:
import csv
# 創(chuàng)建包含特殊字符的CSV數(shù)據(jù)
special_data = [
['姓名', '描述'],
['張三', '喜歡"Python"編程'],
['李四', '愛好: 讀書, 游泳, 旅行'],
['王五', '地址: 北京市朝陽區(qū)\n郵編: 100000']
]
with open('special.csv', 'w', newline='', encoding='utf-8') as file:
writer = csv.writer(file, quoting=csv.QUOTE_ALL)
writer.writerows(special_data)
print("已創(chuàng)建包含特殊字符的CSV文件 'special.csv'")
# 讀取包含特殊字符的CSV文件
with open('special.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
for row_num, row in enumerate(reader, 1):
print(f"第{row_num}行: {row}")
注意事項(xiàng):
- 使用
quoting=csv.QUOTE_ALL可以確保特殊字符被正確處理 - 包含逗號(hào)、引號(hào)或換行符的字段會(huì)被自動(dòng)加上引號(hào)
- 讀取時(shí)這些特殊字符會(huì)被正確解析
3. 實(shí)用示例
3.1 CSV數(shù)據(jù)統(tǒng)計(jì)
示例:統(tǒng)計(jì)不同城市的員工數(shù)量
import csv
def count_employees_by_city(csv_file):
"""統(tǒng)計(jì)不同城市的員工數(shù)量"""
city_count = {}
with open(csv_file, 'r', encoding='utf-8') as file:
dict_reader = csv.DictReader(file)
for row in dict_reader:
city = row['城市']
if city in city_count:
city_count[city] += 1
else:
city_count[city] = 1
return city_count
# 示例使用
if __name__ == "__main__":
# 假設(shè)employees.csv文件已存在
city_counts = count_employees_by_city('employees.csv')
print("各城市員工數(shù)量統(tǒng)計(jì):")
for city, count in city_counts.items():
print(f" {city}: {count}人")
3.2 CSV數(shù)據(jù)轉(zhuǎn)換
示例:將CSV數(shù)據(jù)轉(zhuǎn)換為JSON格式
import csv
import json
def csv_to_json(csv_file, json_file):
"""將CSV文件轉(zhuǎn)換為JSON文件"""
data = []
with open(csv_file, 'r', encoding='utf-8') as file:
dict_reader = csv.DictReader(file)
for row in dict_reader:
data.append(row)
with open(json_file, 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=2)
print(f"已將 {csv_file} 轉(zhuǎn)換為 {json_file}")
# 示例使用
if __name__ == "__main__":
csv_to_json('employees.csv', 'employees.json')
3.3 CSV數(shù)據(jù)過濾
示例:過濾特定條件的記錄
import csv
def filter_employees_by_age(csv_file, min_age):
"""過濾年齡大于等于指定值的員工"""
filtered_data = []
with open(csv_file, 'r', encoding='utf-8') as file:
dict_reader = csv.DictReader(file)
fieldnames = dict_reader.fieldnames
for row in dict_reader:
if int(row['年齡']) >= min_age:
filtered_data.append(row)
# 保存過濾結(jié)果
output_file = f'employees_age_{min_age}+.csv'
with open(output_file, 'w', newline='', encoding='utf-8') as file:
dict_writer = csv.DictWriter(file, fieldnames=fieldnames)
dict_writer.writeheader()
dict_writer.writerows(filtered_data)
print(f"已過濾并保存結(jié)果到 {output_file}")
return filtered_data
# 示例使用
if __name__ == "__main__":
filtered = filter_employees_by_age('employees.csv', 30)
print(f"過濾后共有 {len(filtered)} 名員工")
3.4 CSV數(shù)據(jù)合并
示例:合并多個(gè)CSV文件
import csv
import os
def merge_csv_files(input_files, output_file):
"""合并多個(gè)CSV文件"""
if not input_files:
print("沒有輸入文件")
return
# 讀取第一個(gè)文件的表頭
with open(input_files[0], 'r', encoding='utf-8') as file:
dict_reader = csv.DictReader(file)
fieldnames = dict_reader.fieldnames
# 合并數(shù)據(jù)
merged_data = []
for csv_file in input_files:
with open(csv_file, 'r', encoding='utf-8') as file:
dict_reader = csv.DictReader(file)
for row in dict_reader:
merged_data.append(row)
# 寫入合并結(jié)果
with open(output_file, 'w', newline='', encoding='utf-8') as file:
dict_writer = csv.DictWriter(file, fieldnames=fieldnames)
dict_writer.writeheader()
dict_writer.writerows(merged_data)
print(f"已合并 {len(input_files)} 個(gè)CSV文件到 {output_file}")
print(f"總記錄數(shù): {len(merged_data)}")
# 示例使用
if __name__ == "__main__":
input_files = ['employees1.csv', 'employees2.csv', 'employees3.csv']
# 過濾存在的文件
input_files = [f for f in input_files if os.path.exists(f)]
if input_files:
merge_csv_files(input_files, 'merged_employees.csv')
else:
print("沒有找到輸入文件")
4. 代碼優(yōu)化建議
- 使用上下文管理器:始終使用
with語句來管理文件操作,確保文件正確關(guān)閉。 - 指定編碼:在打開文件時(shí)明確指定
encoding='utf-8',確保正確處理中文字符。 - 錯(cuò)誤處理:添加適當(dāng)?shù)腻e(cuò)誤處理,如
FileNotFoundError、PermissionError等。 - 選擇合適的讀寫方式:
- 對于簡單的CSV文件,使用
csv.reader和csv.writer - 對于帶標(biāo)題的CSV文件,使用
csv.DictReader和csv.DictWriter
- 對于簡單的CSV文件,使用
- 處理大文件:對于大型CSV文件,考慮使用生成器表達(dá)式或分塊處理,避免一次性加載所有數(shù)據(jù)到內(nèi)存。
- 自定義分隔符:當(dāng)處理非標(biāo)準(zhǔn)CSV文件時(shí),記得指定正確的分隔符。
- 引用符設(shè)置:根據(jù)數(shù)據(jù)特點(diǎn)選擇合適的引用模式,確保特殊字符被正確處理。
- 字段名處理:使用
DictReader時(shí),注意CSV文件的第一行是否包含字段名。 - 數(shù)據(jù)類型轉(zhuǎn)換:CSV文件中的數(shù)據(jù)默認(rèn)都是字符串類型,需要根據(jù)需要進(jìn)行類型轉(zhuǎn)換。
- 性能優(yōu)化:對于大量數(shù)據(jù)的讀寫,考慮使用
csv模塊的快速模式,或使用第三方庫如pandas。
5. 常見問題與解決方案
5.1 問題:CSV文件中包含中文字符導(dǎo)致亂碼
解決方案:在打開文件時(shí)明確指定encoding='utf-8',確保中文字符被正確處理。
5.2 問題:CSV文件讀取時(shí)出現(xiàn)額外的空行
解決方案:在打開文件時(shí)設(shè)置newline='',避免Python的換行符處理與CSV模塊的處理沖突。
5.3 問題:CSV文件中的數(shù)字被讀取為字符串
解決方案:在讀取后手動(dòng)將需要的字段轉(zhuǎn)換為數(shù)字類型,例如:age = int(row['年齡'])。
5.4 問題:CSV文件中的字段包含逗號(hào)或引號(hào)
解決方案:使用適當(dāng)?shù)囊媚J?,?code>quoting=csv.QUOTE_ALL,確保特殊字符被正確處理。
5.5 問題:DictReader讀取時(shí)字段名包含空格
解決方案:可以在讀取后手動(dòng)處理字段名,去除空格,或者在寫入時(shí)確保字段名不包含空格。
5.6 問題:大型CSV文件讀取內(nèi)存不足
解決方案:使用迭代器逐行讀取,避免一次性加載所有數(shù)據(jù)到內(nèi)存。
5.7 問題:寫入CSV文件時(shí)日期格式不正確
解決方案:在寫入前將日期轉(zhuǎn)換為適當(dāng)?shù)淖址袷?,例如?code>date.strftime('%Y-%m-%d')。
6. 總結(jié)
CSV文件是一種簡單而廣泛使用的數(shù)據(jù)交換格式,Python的csv模塊提供了強(qiáng)大的功能來處理CSV文件。通過本教程,你應(yīng)該已經(jīng)了解了:
- 如何使用
csv.reader和csv.writer進(jìn)行基本的CSV讀寫操作 - 如何使用
csv.DictReader和csv.DictWriter以字典形式處理CSV數(shù)據(jù) - 如何自定義分隔符和引用符
- 如何處理CSV中的特殊情況
- 實(shí)用的CSV數(shù)據(jù)處理示例
- 常見問題的解決方案
在實(shí)際應(yīng)用中,CSV文件處理是一個(gè)常見的任務(wù),無論是數(shù)據(jù)導(dǎo)入導(dǎo)出、數(shù)據(jù)清洗還是數(shù)據(jù)分析,都需要掌握這些基本技能。通過不斷練習(xí)和實(shí)踐,你將能夠更加高效地處理各種CSV文件操作任務(wù)。
對于更復(fù)雜的CSV處理需求,你還可以考慮使用第三方庫如pandas,它提供了更高級(jí)的CSV處理功能,如數(shù)據(jù)框操作、數(shù)據(jù)篩選、聚合等。
以上就是Python中處理CSV文件的核心方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Python處理CSV文件方法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
通過Python調(diào)用MCP的實(shí)現(xiàn)示例
本文主要介紹了Python代碼連接SSE格式的MCPServer以及如何連接多個(gè)MCPServer,通過合理的類庫和邏輯拆分,可以實(shí)現(xiàn)更高效地調(diào)用MCP,下面就來詳細(xì)的介紹一下,感興趣的可以了解一下2025-12-12
Pyinstaller打包報(bào)錯(cuò)小結(jié)
本文主要介紹了Pyinstaller打包報(bào)錯(cuò)小結(jié),詳細(xì)的介紹了5種錯(cuò)誤的解決方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02
回調(diào)函數(shù)的意義以及python實(shí)現(xiàn)實(shí)例
本篇文章主要介紹了回調(diào)函數(shù)的意義以及python實(shí)現(xiàn)實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
python內(nèi)置函數(shù)globals()的實(shí)現(xiàn)代碼
本文主要介紹了python內(nèi)置函數(shù)globals()的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
Python數(shù)據(jù)庫的連接實(shí)現(xiàn)方法與注意事項(xiàng)
這篇文章主要介紹了Python數(shù)據(jù)庫的連接實(shí)現(xiàn)方法與注意事項(xiàng),需要的朋友可以參考下2016-02-02
Python?提取出SQL語句中Where的值兩種方法(示例代碼)
為了提取SQL語句中WHERE子句的值,我們可以利用Python的sqlparse庫,這是一個(gè)專門用于解析SQL語句的庫,這篇文章主要介紹了Python?提取出SQL語句中Where的值的方法,需要的朋友可以參考下2024-08-08
Python使用requests及BeautifulSoup構(gòu)建爬蟲實(shí)例代碼
這篇文章主要介紹了Python使用requests及BeautifulSoup構(gòu)建爬蟲,介紹了具體操作步驟和實(shí)例代碼等相關(guān)內(nèi)容,小編覺得還是挺不錯(cuò)的,這里分享給大家,需要的朋友可以參考下2018-01-01
Python計(jì)數(shù)器collections.Counter用法詳解
本文主要介紹了Python計(jì)數(shù)器collections.Counter用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03

