百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

读写 CSV 数据

bigegpt 2024-09-20 13:58 3 浏览

1. 现象

读写一个 CSV 格式的文件

2. 原因分析

3. 问题解决

对于大多数的 CSV 格式的数据读写问题,都可以使用 csv 库,常见的例子:

Output.csv内容

import csv

with open('Output.csv', newline='') as f_obj:
    c_reader = csv.reader(f_obj)
    headers = next(c_reader)
    for line in c_reader:
        print(line)

"""
['A', 'B', 'C']
['1', '2', '3']
['第', '一', '个']
"""

在上边的代码中,line 是一个序列 list,如果需要访问某个字段,可以使用下标的方式访问 line[0]

由于下标访问通常会引起混淆,可以考虑使用命名元组

import csv
from collections import namedtuple

with open('Output.csv', newline='') as f_obj:
    c_reader = csv.reader(f_obj)
    headers = next(c_reader)
    Line = namedtuple('Line', headers)
    for i_line in c_reader:
        line = Line(*i_line)
        print(line)
        print(line.行中)

"""
Line(行首='A', 行中='B', 行尾='C')
B
Line(行首='1', 行中='2', 行尾='3')
2
Line(行首='第', 行中='一', 行尾='个')
一
"""

namedtuple 允许使用列名如 row.行首 和 row.行中 代替下标访问。需要注意的是这个只有在列名是合法的 Python 标识符的时候才生效。如果不是的话,可能需要修改原始的列名 (如将非标识符字符替换成下划线之类的)

另外一个选择就是将数据读取到一个字典序列中去。可以这样做:

with open('Output.csv', newline='') as f_obj:
    c_reader = csv.DictReader(f_obj)
    for line in c_reader:
        print(line['行中'])

"""
B
2
一
"""

在这个版本中,可以使用列名去访问每一行的数据了。比如, row['行中'] 或者 row['行首']

为了写入 CSV 数据,也可以使用 csv 模块,不过这时候先创建一个 writer 对象

headers = ['行首', '行中', '行尾']
data = [
    ('A', 'B', 'C'),
    [1, 2, 3],
    ('第', '一', '个'),
]

# newline = '' 保证Windows下不会换行
with open('Input.csv', 'w', newline='') as f_obj:
    w_csv = csv.writer(f_obj)
    w_csv.writerow(headers)
    w_csv.writerows(data)

如果不添加 newline = '' ,则Windows下会换行

headers = ['行首', '行中', '行尾']
data = [
    ('A', 'B', 'C'),
    [1, 2, 3],
    ('第', '一', '个'),
]

with open('Input.csv', 'w') as f_obj:
    w_csv = csv.writer(f_obj)
    w_csv.writerow(headers)
    w_csv.writerows(data)

如果有一个字典序列的数据,可以像这样做

headers = ['行首', '行中', '行尾']
data = [
    {'行首': 'A', '行中': 'B', '行尾': 'C'},
    {'行首': 1, '行中': 2, '行尾': 3},
    {'行首': '第', '行中': '一', '行尾': '个'},
]

with open('Input.csv', 'w', newline='') as f_obj:
    w_csv = csv.DictWriter(f_obj, fieldnames=headers)
    w_csv.writeheader()
    w_csv.writerows(data)

应该总是优先选择 csv 模块分割或解析 CSV 数据,例如,你可能会像编写类似下面这样的代码

with open('Output.csv', newline='') as f_obj:
    for line in f_obj:
        row = line.split(',')
        print(row)

使用这种方式的一个缺点就是仍然需要去处理一些棘手的细节问题。比如

  • 如果某些字段值被引号包围,你不得不去除这些引号
  • 如果一个被引号包围的字段碰巧含有一个逗号,那么程序就会因为产生一个错误大小的行而出错

默认情况下, csv 库可识别 Microsoft Excel 所使用的 CSV 编码规则。这或许也是最常见的形式,并且也会给你带来最好的兼容性。然而,如果你查看 csv 的文档,就会发现有很多种方法将它应用到其他编码格式上 (如修改分割字符等)。例如,如果你想读取以 tab 分割的数据,可以这样做

with open('Output.csv', newline='') as f_obj:
    c_reader = csv.reader(f_obj, delimiter='\t')
    headers = next(c_reader)
    for line in c_reader:
        print(line)

如果正在读取 CSV 数据并将它们转换为命名元组,需要注意对列名进行合法性认证。例如,一个 CSV 格式文件有一个包含非法标识符的列头行,类似下面这样:

import re

with open('Output.csv') as f_obj:
    c_csv = csv.reader(f_obj)
    headers = [re.sub('[^a-zA-Z_]', '_', header) for header in next(c_csv) ]
    Line = namedtuple('Line', headers)
    for i_line in c_csv:
        row = Line(*i_line)

如果含有非法标识符,会导致在创建一个命名元组时产生一个 ValueError 异常而失败。为了解决这问题,你可能不得不先去修正列标题。例如,可以像上面这样在非法标识符上使用一个正则表达式替换,当然这里是很简单的替换,更加有效的判断需要单独写函数

还有重要的一点需要强调的是, csv 产生的数据都是字符串类型的,它不会做任何其他类型的转换。如果需要做这样的类型转换,必须自己手动去实现

先更改Input.csv数据内容为:

col_types = [str, int, str]

with open('Input.csv', newline='') as f_obj:
    c_csv = csv.reader(f_obj)
    headers = next(c_csv)
    for line in c_csv:
        row = tuple(convert(value) for convert, value in zip(col_types, line))
        print(row)

"""
('A', 1, 'C')
('1', 2, '3')
('第', 3, '个')
"""

col_types = [
    ('行首', str),
    ('行中', int),
    ('行尾', str),
]

with open('Input.csv', newline='') as f_obj:
    c_csv = csv.DictReader(f_obj)
    for line in c_csv:
        line.update((key, convert(line[key])) for key, convert in col_types)
        print(line)

"""
OrderedDict([('行首', 'A'), ('行中', 1), ('行尾', 'C')])
OrderedDict([('行首', '1'), ('行中', 2), ('行尾', '3')])
OrderedDict([('行首', '第'), ('行中', 3), ('行尾', '个')])
"""

通常来讲,我们可能并不想过多去考虑这些转换问题。

但在实际情况中, CSV 文件都或多或少有些缺失的数据,被破坏的数据以及其它一些转换失败的问题。因此,除非你的数据确实有保障是准确无误的,否则你必须考虑这些问题 (你可能需要增加合适的错误处理机制)

最后,如果读取 CSV 数据的目的是做数据分析和统计的话,我们可以看一看 Pandas 包。 Pandas 包含了一个非常方便的函数叫 pandas.read_csv() ,它可以加载 CSV 数据到一个 DataFrame 对象中去。然后利用这个对象我们就可以生成各种形式的统计、过滤数据以及执行其他高级操作。

4. 错误经历

相关推荐

方差分析简介(方差分析通俗理解)

介绍方差分析(ANOVA,AnalysisofVariance)是一种广泛使用的统计方法,用于比较两个或多个组之间的均值。单因素方差分析是方差分析的一种变体,旨在检测三个或更多分类组的均值是否存在...

正如404页面所预示,猴子正成为断网元凶--吧嗒吧嗒真好吃

吧嗒吧嗒,绘图:MakiNaro你可以通过加热、冰冻、水淹、模塑、甚至压溃压力来使网络光缆硬化。但用猴子显然是不行的。光缆那新挤压成型的塑料外皮太尼玛诱人了,无法阻挡一场试吃盛宴的举行。印度政府正...

Python数据可视化:箱线图多种库画法

概念箱线图通过数据的四分位数来展示数据的分布情况。例如:数据的中心位置,数据间的离散程度,是否有异常值等。把数据从小到大进行排列并等分成四份,第一分位数(Q1),第二分位数(Q2)和第三分位数(Q3)...

多组独立(完全随机设计)样本秩和检验的SPSS操作教程及结果解读

作者/风仕在上一期,我们已经讲完了两组独立样本秩和检验的SPSS操作教程及结果解读,这期开始讲多组独立样本秩和检验,我们主要从多组独立样本秩和检验介绍、两组独立样本秩和检验使用条件及案例的SPSS操作...

方差分析 in R语言 and Excel(方差分析r语言例题)

今天来写一篇实际中比较实用的分析方法,方差分析。通过方差分析,我们可以确定组别之间的差异是否超出了由于随机因素引起的差异范围。方差分析分为单因素方差分析和多因素方差分析,这一篇先介绍一下单因素方差分析...

可视化:前端数据可视化插件大盘点 图表/图谱/地图/关系图

前端数据可视化插件大盘点图表/图谱/地图/关系图全有在大数据时代,很多时候我们需要在网页中显示数据统计报表,从而能很直观地了解数据的走向,开发人员很多时候需要使用图表来表现一些数据。随着Web技术的...

matplotlib 必知的 15 个图(matplotlib各种图)

施工专题,我已完成20篇,施工系列几乎覆盖Python完整技术栈,目标只总结实践中最实用的东西,直击问题本质,快速帮助读者们入门和进阶:1我的施工计划2数字专题3字符串专题4列表专题5流程控制专题6编...

R ggplot2常用图表绘制指南(ggplot2绘制折线图)

ggplot2是R语言中强大的数据可视化包,基于“图形语法”(GrammarofGraphics),通过分层方式构建图表。以下是常用图表命令的详细指南,涵盖基本语法、常见图表类型及示例,适合...

Python数据可视化:从Pandas基础到Seaborn高级应用

数据可视化是数据分析中不可或缺的一环,它能帮助我们直观理解数据模式和趋势。本文将全面介绍Python中最常用的三种可视化方法。Pandas内置绘图功能Pandas基于Matplotlib提供了简洁的绘...

Python 数据可视化常用命令备忘录

本文提供了一个全面的Python数据可视化备忘单,适用于探索性数据分析(EDA)。该备忘单涵盖了单变量分析、双变量分析、多变量分析、时间序列分析、文本数据分析、可视化定制以及保存与显示等内容。所...

统计图的种类(统计图的种类及特点图片)

统计图是利用几何图形或具体事物的形象和地图等形式来表现社会经济现象数量特征和数量关系的图形。以下是几种常见的统计图类型及其适用场景:1.条形图(BarChart)条形图是用矩形条的高度或长度来表示...

实测,大模型谁更懂数据可视化?(数据可视化和可视化分析的主要模型)

大家好,我是Ai学习的老章看论文时,经常看到漂亮的图表,很多不知道是用什么工具绘制的,或者很想复刻类似图表。实测,大模型LaTeX公式识别,出乎预料前文,我用Kimi、Qwen-3-235B...

通过AI提示词让Deepseek快速生成各种类型的图表制作

在数据分析和可视化领域,图表是传达信息的重要工具。然而,传统图表制作往往需要专业的软件和一定的技术知识。本文将介绍如何通过AI提示词,利用Deepseek快速生成各种类型的图表,包括柱状图、折线图、饼...

数据可视化:解析箱线图(box plot)

箱线图/盒须图(boxplot)是数据分布的图形表示,由五个摘要组成:最小值、第一四分位数(25th百分位数)、中位数、第三四分位数(75th百分位数)和最大值。箱子代表四分位距(IQR)。IQR是...

[seaborn] seaborn学习笔记1-箱形图Boxplot

1箱形图Boxplot(代码下载)Boxplot可能是最常见的图形类型之一。它能够很好表示数据中的分布规律。箱型图方框的末尾显示了上下四分位数。极线显示最高和最低值,不包括异常值。seaborn中...