一、csv格式介绍

CSV是一种以纯文本格式存储表格数据的文件格式。每一行代表一条数据记录,每条记录由一个或多个字段组成。字段分隔符默认使用逗号分隔,实际使用中也可以采用其他字符作为分隔符,如分号 **;**或制表符 **\t**等。

1.1、基本结构

  • 每一行:表示一条数据记录。
  • 字段:记录中的每个数据项,用字段分隔符分隔。
  • 字段值:文本或数字,可以包含特殊字符。
Name,Age,Email
John,25,john@example.com
Emma,32,emma@example.com

1.2、特殊情况

​ 字段中若包含回车换行符、双引号或者逗号,该字段需要用双引号括起来。如果用双引号括字段,那么出现在字段内的双引号前必须加一个双引号进行转义。

"aaa","b 
bb","ccc"

"aaa","b""bb","ccc"

二、解析csv常用的库

2.1、open()+ 手动解析

文本文件都可以用open()方式读取后根据文本的格式进行手动解析,但是这种方式不太推荐使用

  • CSV 文件可能有特殊格式,比如字段中包含逗号、换行符、引号等,直接按行分割容易出错;
  • 不同操作系统可能使用不同的换行符
  • 有些 CSV 使用分号(😉、制表符(\t) 等作为分隔符,而不是逗号;没法做到通用
  • csv 模块或者pandas模块可以自动处理这些复杂情况,让你专注于数据本身。

2.2、csv模块

Python的csv库是一个内置的标准库,它提供了一系列的工具,用于读取和写入CSV文件。这个库支持多种类型的CSV文件,包括那些使用不同分隔符和引号的文件。通过csv库,我们可以轻松地将数据从CSV文件中读取到Python的数据结构中,或者将数据结构写入到CSV文件中。

2.3、pandas模块

pandas是 Python 中一个功能极其强大且广泛使用的数据分析和处理库,特别适合处理结构化数据(比如表格数据,类似 Excel、SQL 表、CSV 等)

三、csv库

csv 模块主要提供以下功能:

  1. 读取 CSV 文件csv.reader
  2. 写入 CSV 文件csv.writer
  3. 以字典形式读写 CSVcsv.DictReader, csv.DictWriter)—— 更加方便
  4. 支持不同的分隔符、引号规则等(通过 csv.Dialect或参数配置)

3.1、 读取 CSV 文件(csv.reader

csv.reader(csvfile, dialect='excel', **fmtparams)
  • 功能:读取 CSV 文件,将每一行解析为列表(或其他格式)供程序处理
  • 参数:
    • csvfile:必需。一个文件对象(通常通过 open()打开),或者是任何可迭代且每次返回一行字符串的对象。
    • dialect:可选。指定 CSV 文件的格式规范。默认是 'excel',也就是标准的 CSV 格式:逗号分隔,双引号包裹字段。支持值为[‘excel’, ‘excel-tab’, ‘unix’]
    • **fmtparams:可选的关键字参数,用于更细致地控制格式,比如 delimiter=‘,’、quotechar='"'等。可以覆盖 dialect的默认设置。常用的就是delimiter指定分隔符
  • 返回值:一个 可迭代对象(reader),每次迭代返回一行(通常是一个列表)
import csv

with open('data.tsv', 'r', encoding='utf-8', newline='') as f:#必须加上参数 newline='',否则在某些操作系统(尤其是 Windows)上可能会出现多余的空行
    reader = csv.reader(f, delimiter='\t')  # 制表符分隔
    for row in reader:
        print(row)# 每一行是一个列表,如 ['name', 'age','john@example.com'], ['Alice', '30','emma@example.com']

3.2、读取 CSV 文件( csv.DictReader)–推荐

csv.DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', **fmtparams)
  • 功能:读取 CSV 文件,将每一行转换为字典,字段名为键,数据为值
  • 参数:
    • csvfile:必需。一个文件对象(通常通过 open()打开),或者是任何可迭代且每次返回一行字符串的对象。
    • fieldnames:可选。指定列名的列表。如果未提供(默认),则使用文件中的第一行作为列名。
    • restkey:可选。如果某行的字段多于列名,多出的字段会存入一个列表,并以该键命名。
    • restval:可选。如果某行的字段少于列名,缺失的字段会用该值填充。
    • dialect:可选。指定 CSV 文件的格式规范。默认是 'excel',也就是标准的 CSV 格式:逗号分隔,双引号包裹字段。支持值为[‘excel’, ‘excel-tab’, ‘unix’]
    • **fmtparams:可选的关键字参数,用于更细致地控制格式,比如 delimiter=‘,’、quotechar='"'等。可以覆盖 dialect的默认设置。常用的就是delimiter指定分隔符
  • 返回值:一个 可迭代对象(reader),每次迭代返回一行(dict)
name,age,city
Alice,23,New York
Bob,30,Los Angeles
Charlie,25,Chicago
import csv

with open('data.csv', 'r', encoding='utf-8', newline='') as f:
    reader = csv.DictReader(f)  # 自动将第一行作为字段名,也可以自己指定列名reader = csv.DictReader(f, fieldnames=fieldnames)
    for row in reader:
        print(row)  # 每一行是一个字典
输出结果:
{'name': 'Alice', 'age': '23', 'city': 'New York'}
{'name': 'Bob', 'age': '30', 'city': 'Los Angeles'}
{'name': 'Charlie', 'age': '25', 'city': 'Chicago'}

3.3、写入 CSV 文件(csv.writer

csv.writer(csvfile, dialect='excel', **fmtparams)
  • 功能:将列表形式的数据(每行是一个列表)写入 CSV 文件
  • 参数:
    • csvfile:必需。一个文件对象(通常通过 open()打开),或者是任何可迭代且每次返回一行字符串的对象。
    • fieldnames:可选。指定列名的列表。如果未提供(默认),则使用文件中的第一行作为列名。
    • **fmtparams:可选的关键字参数,用于更细致地控制格式,比如 delimiter=‘,’、quotechar='"'等。可以覆盖 dialect的默认设置。常用的就是delimiter指定分隔符
  • 返回值:返回一个 writer对象,用于执行写入操作

csv.writer对象提供如下常用方法:

方法 说明
writerow(row) 写入单行数据row是一个列表,如 ['Alice', 23]
writerows(rows) 写入多行数据rows是一个列表的列表,如 [ ['A',1], ['B',2] ]
import csv

data = [
    ['name', 'age', 'city'],
    ['Alice', 23, 'New York'],
    ['Bob', 30, 'Los Angeles'],
    ['Charlie', 25, 'Chicago']
]

with open('output.csv', mode='w', encoding='utf-8', newline='') as file:
    writer = csv.writer(file)
    writer.writerows(data)

3.4、写入 CSV 文件(使用 csv.DictWriter)–推荐

csv.DictWriter(csvfile, fieldnames, restval="", extrasaction="raise", dialect="excel", **fmtparams)
  • 功能:读取 CSV 文件,将每一行转换为字典,字段名为键,数据为值
  • 参数:
    • csvfile:必需。一个文件对象(通常通过 open()打开),用于数据写入。
    • fieldnames:必需。一个列表,指定 CSV 文件的列名(表头),如 ['name', 'age', 'city']
      字典的键必须与 fieldnames中的字段名一致。
    • restval:可选。如果某行的字典缺少某些字段(即字段名不在字典的 key 中),缺失字段会用此值填充,默认为空字符串 ''
    • extrasaction:选。如果字典中包含了 fieldnames之外的字段,如何处理:
      - 'raise'(默认):抛出异常
      - 'ignore':忽略多余的字段
    • dialect:可选。指定 CSV 文件的格式规范。默认是 'excel',也就是标准的 CSV 格式:逗号分隔,双引号包裹字段。支持值为[‘excel’, ‘excel-tab’, ‘unix’]
    • **fmtparams:可选的关键字参数,用于更细致地控制格式,比如 delimiter=‘,’、quotechar='"'等。可以覆盖 dialect的默认设置。常用的就是delimiter指定分隔符
  • 返回值:返回一个 DictWriter对象,用于执行写入操作

csv.DictWriter对象的常用方法汇总

方法 说明
writeheader() 写入 CSV 文件的表头(列名),即 fieldnames中的字段名
writerow(row_dict) 写入单行数据,参数是一个字典,键必须与 fieldnames一致
writerows(rows_list) 写入多行数据,参数是一个字典的列表(每个字典是一行)
import csv

headers = ['name', 'age', 'city']
rows = [
    {'name': 'Alice', 'age': 23, 'city': 'New York'},
    {'name': 'Bob', 'age': 30, 'city': 'Los Angeles'},
    {'name': 'Charlie', 'age': 25, 'city': 'Chicago'}
]

with open('output_dict.csv', mode='w', encoding='utf-8', newline='') as file:
    writer = csv.DictWriter(file, fieldnames=headers)
    writer.writeheader()  # 写入表头
    writer.writerows(rows)  # 写入多行数据

3.5、csv.readercsv.DictReader对比

特性 csv.reader() csv.DictReader()
返回类型 每行是一个 列表(list) 每行是一个 字典(dict)
字段访问方式 通过索引,如 row[0] 通过列名(键),如 row['name']
是否需要列名 否(但你可以自己处理) 通常是(第一行作为列名,也可手动指定)
代码可读性 一般,依赖索引 更高,字段名清晰直观
适用场景 简单、快速处理,字段顺序固定 需要按列名访问,更易维护

3.6、csv.writercsv.DictWriter对比

特性 csv.writer csv.DictWriter
输入数据类型 每行是一个 列表(list),如 ['Alice', 23] 每行是一个 字典(dict),如 {'name': 'Alice', 'age': 23}
是否需要列名 否(但你可以自己写入表头) 通常是(第一行作为列名,或通过 fieldnames指定)
适用场景 数据是列表形式,字段顺序固定 数据是字典形式,字段名清晰,更灵活易读
写入方法 writerow(row)writerows(rows) writeheader()writerow(row_dict)writerows(rows_list)

3.7、高级用法

自定义dialect,然后复用。实际上fmtparams就是在修改dialect,可以直接自定定义一个。

Dialect类支持以下属性

属性名 描述 默认值
delimiter 字段分隔符,单字符 ','
doublequote 控制字段中引号字符的引出方式,True表示双写引号字符,False表示在引号字符前加转义符 True
escapechar 用于转义定界符(quotingQUOTE_NONE时)或引号字符(doublequoteFalse时)的单字符 None(禁用转义)
lineterminator writer产生的行的结尾字符 '\r\n'
quotechar 用于包住含有特殊字符字段的单字符 '"'
quoting 控制writer生成引号和reader识别引号的时机,可设为QUOTE_*常量 QUOTE_MINIMAL
skipinitialspace 是否忽略紧跟在分隔符后的空格 False
strict 输入错误的 CSV 时是否抛出Error异常 False
import csv

csv.register_dialect('mydialect',
                     delimiter='|',
                     quotechar='"',
                     quoting=csv.QUOTE_MINIMAL)

with open('dialect_example.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f, dialect='mydialect')
    writer.writerow(['Name', 'Age'])
    writer.writerow(['Alice', 30])

四、pandas库

pandas解析csv数据主要是两个函数read_csv()和to_csv()

4.1、读取csv-read_csv()

pandas.read_csv(filepath_or_buffer, sep=',', header='infer', names=None, encoding='utf-8', ...)

作用:读取 CSV(或类 CSV,如 TSV)文件,返回一个 pandas DataFrame。

常用参数如下:

参数 说明 示例/默认值
filepath_or_buffer 必需。CSV 文件路径(可以是本地路径或 URL) 'data.csv''https://example.com/data.csv'
sepdelimiter 字段分隔符,默认是 ,(逗号) sep=','sep='\t'(制表符,TSV 文件)
header 指定哪一行作为列名(表头) - header=0(默认):第一行是列名 - header=None:没有列名,pandas 会自动生成数字列名(0, 1, 2…) header=0(默认) 或 header=None
names 自定义列名(当 header=None时特别有用) names=['col1', 'col2', 'col3']
encoding 文件编码,如 'utf-8''gbk'(中文 Windows 常见) encoding='utf-8''gbk'
index_col 指定某一列作为行索引(默认是自动生成数字索引) index_col='name'index_col=0
usecols 只读取指定的列,可以是列名列表或索引列表 usecols=['name', 'age']
dtype 指定列的数据类型,如 {'age': 'int32'} dtype={'age': int}
na_values 指定哪些值应被视为缺失值(NaN) na_values=['NA', 'null', '']
skiprows 跳过文件开头的若干行(可以是数字或列表) skiprows=1跳过第一行
nrows 只读取前 N 行数据 nrows=10只读取前 10 行
engine 指定解析引擎,如 'c'(默认,快)或 'python'(功能更全) engine='python'

read_csv()对象的常用方法:

方法 作用
df.head(n) 查看前 n 行(默认 5 行)
df.tail(n) 查看后 n 行
df.info() 查看列名、非空数量、数据类型等
df.describe() 数值列的统计摘要(均值、标准差、最值等)
df.shape 查看数据行数和列数,如 (100, 5)
df.columns 查看所有列名
df.isnull().sum() 查看每列缺失值的数量
# 自定义分隔符
# 添加自定义表头
df = pd.read_csv('data_no_header.csv', sep=',', header=None, names=['name', 'age', 'city'])
print(df)
"""    
name  age         city
0  Alice   23     New York
1    Bob   30  Los Angeles
"""

df.to_csv("data.csv")

# 只读取部分列
df2 = pd.read_csv('data.csv', usecols=['name', 'age'])
print(df2)
"""
    name  age
0  Alice   23
1    Bob   30
"""

# 跳过前几行(比如文件开头有注释)
df3 = pd.read_csv('data.csv', skiprows=0)
print(df3)
"""
   0 Alice  23     New York
0  1   Bob  30  Los Angeles
"""

# 只显示前面几行
df4 = pd.read_csv('data.csv', nrows=2)
print(df4)
"""
   Unnamed: 0   name  age         city
0           0  Alice   23     New York
1           1    Bob   30  Los Angeles
"""

print(df.info())
print(df.describe())
print(df.shape)
print(df.columns)
print(df.head(1))

4.2、写入csv

DataFrame.to_csv(
    path_or_buf=None,      # 文件路径(必需)
    sep=',',               # 分隔符,默认是逗号 ','
    na_rep='',             # 缺失值(NaN)的替代字符串,默认为空字符串
    float_format=None,     # 浮点数格式化字符串
    columns=None,          # 指定要写入的列(列名列表)
    header=True,           # 是否写入列名(表头),默认为 True
    index=True,            # 是否写入行索引,默认为 True
    index_label=None,      # 行索引的列名(当 index=True 时)
    encoding=None,         # 文件编码,如 'utf-8', 'gbk'
    mode='w',              # 写入模式:'w' 覆盖写入,'a' 追加写入
    quoting=None,          # 控制引用规则
    quotechar='"',         # 引号字符,默认为双引号
    line_terminator='\n',  # 行终止符
    chunksize=None,        # 分块写入(大数据时使用)
    date_format=None,      # 日期格式化
    decimal='.',           # 小数点符号,如 '.' 或 ','
    **kwargs
)
import pandas as pd

# 创建一个示例 DataFrame
data = {
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [23, 30, 25],
    'city': ['New York', 'Los Angeles', 'Chicago']
}

df = pd.DataFrame(data)

# 将 DataFrame 保存为 CSV 文件
df.to_csv('output.csv', index=False)  # 不保存行索引
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐