如何读写 CSV 文件?
- 2024-11-25 08:49:00
- admin 原创
- 255
问题描述:
如何读取以下 CSV 文件?
1,"A towel,",1.0
42," it says, ",2.0
1337,is about the most ,-1
0,massively useful thing ,123
-2,an interstellar hitchhiker can have.,3
如何将以下内容写入data
CSV 文件?
data = [
(1, "A towel,", 1.0),
(42, " it says, ", 2.0),
(1337, "is about the most ", -1),
(0, "massively useful thing ", 123),
(-2, "an interstellar hitchhiker can have.", 3),
]
解决方案 1:
这里有一些关于如何读取 CSV 文件以及如何使用 Python 写入 CSV 文件的最小完整示例。
纯 Python:
import csv
# Define data
data = [
(1, "A towel,", 1.0),
(42, " it says, ", 2.0),
(1337, "is about the most ", -1),
(0, "massively useful thing ", 123),
(-2, "an interstellar hitchhiker can have.", 3),
]
# Write CSV file
with open("test.csv", "wt") as fp:
writer = csv.writer(fp, delimiter=",")
# writer.writerow(["your", "header", "foo"]) # write header
writer.writerows(data)
# Read CSV file
with open("test.csv") as fp:
reader = csv.reader(fp, delimiter=",", quotechar='"')
# next(reader, None) # skip the headers
data_read = [row for row in reader]
print(data_read)
之后的内容data_read
是
[['1', 'A towel,', '1.0'],
['42', ' it says, ', '2.0'],
['1337', 'is about the most ', '-1'],
['0', 'massively useful thing ', '123'],
['-2', 'an interstellar hitchhiker can have.', '3']]
请注意,CSV 仅读取字符串。您需要手动转换为列类型。
之前有一个 Python 2+3 版本 (链接),但Python 2 支持已被放弃。删除 Python 2 内容大大简化了这个答案。
有关的
如何将数据以字符串(而不是文件)的形式写入 csv 格式?
如何将 io.StringIO() 与 csv 模块一起使用?:如果您想使用 Flask 即时提供 CSV,而不实际将 CSV 存储在服务器上,这将很有趣。
微处理器
看一下我的实用程序包mpu
,它非常简单且易于记忆:
import mpu.io
data = mpu.io.read('example.csv', delimiter=',', quotechar='"', skiprows=None)
mpu.io.write('example.csv', data)
熊猫
import pandas as pd
# Read the CSV into a pandas data frame (df)
# With a df you can do many things
# most important: visualize data with Seaborn
df = pd.read_csv('myfile.csv', sep=',')
print(df)
# Or export it in many ways, e.g. a list of tuples
tuples = [tuple(x) for x in df.values]
# or export it as a list of dicts
dicts = df.to_dict().values()
请参阅read_csv
文档了解更多信息。请注意,pandas 会自动推断是否存在标题行,但您也可以手动设置。
如果你还没有听说过Seaborn,我建议你看一下。
其他
许多其他库支持读取 CSV 文件,例如:
dask.dataframe.read_csv
spark.read.csv
已创建 CSV 文件
1,"A towel,",1.0
42," it says, ",2.0
1337,is about the most ,-1
0,massively useful thing ,123
-2,an interstellar hitchhiker can have.,3
常见文件结尾
.csv
处理数据
将 CSV 文件读取为元组/字典列表或 Pandas 数据框后,它只是处理这种类型的数据。与 CSV 无关。
替代方案
JSON:适合编写人类可读的数据;非常常用(读取和写入)
CSV:超级简单格式(读写)
YAML:易于阅读,类似于 JSON(读写)
pickle:一种 Python 序列化格式(读写)
MessagePack(Python 包):更紧凑的表示(读取和写入)
HDF5(Python 包):适用于矩阵(读写)
XML:也存在 叹息 (读写)
对于您的应用程序,以下内容可能很重要:
其他编程语言的支持
读写性能
紧凑性(文件大小)
另请参阅:数据序列化格式比较
如果你正在寻找创建配置文件的方法,你可能需要阅读我的短文《Python 中的配置文件》
解决方案 2:
如果您正在处理 CSV 数据,并且想要一个比占用空间更小的解决方案pandas
,您可以尝试我的软件包littletable。 可以通过 pip 安装,也可以直接将其作为单个 .py 文件放入您自己的代码中,因此非常便携,适合无服务器应用程序。
读取 CSV 数据非常简单,只需调用csv_import
:
data = """\n1,"A towel,",1.0
42," it says, ",2.0
1337,is about the most ,-1
0,massively useful thing ,123
-2,an interstellar hitchhiker can have.,3"""
import littletable as lt
tbl = lt.Table().csv_import(data, fieldnames="number1,words,number2".split(','))
tbl.present()
印刷:
Number1 Words Number2
──────────────────────────────────────────────────────────
1 A towel, 1.0
42 it says, 2.0
1337 is about the most -1
0 massively useful thing 123
-2 an interstellar hitchhiker can have. 3
(littletable
使用丰富的模块来呈现表格。)
littletable
不会自动尝试转换数字数据,因此数字列需要数字转换函数。
def get_numeric(s):
try:
return int(s)
except ValueError:
try:
return float(s)
except ValueError:
return s
tbl = lt.Table().csv_import(
data,
fieldnames="number1,words,number2".split(','),
transforms={}.fromkeys("number1 number2".split(), get_numeric)
)
tbl.present()
得出:
Number1 Words Number2
──────────────────────────────────────────────────────────
1 A towel, 1.0
42 it says, 2.0
1337 is about the most -1
0 massively useful thing 123
-2 an interstellar hitchhiker can have. 3
数字列是右对齐的,而不是左对齐的。
littletable
还具有其他 ORM 式的功能,例如索引、连接、透视和全文搜索。以下是数字列的统计表:
tbl.stats("number1 number2".split()).present()
Name Mean Min Max Variance Std_Dev Count Missing
────────────────────────────────────────────────────────────────────────────────
number1 275.6 -2 1337 352390.3 593.6247130974249 5 0
number2 25.6 -1 123 2966.8 54.468339427597755 5 0
或转置:
tbl.stats("number1 number2".split(), by_field=False).present()
Stat Number1 Number2
───────────────────────────────────────────────────
mean 275.6 25.6
min -2 -1
max 1337 123
variance 352390.3 2966.8
std_dev 593.6247130974249 54.468339427597755
count 5 5
missing 0 0
也可以输出其他格式,例如Markdown:
print(tbl.stats("number1 number2".split(), by_field=False).as_markdown())
| stat | number1 | number2 |
|---|---:|---:|
| mean | 275.6 | 25.6 |
| min | -2 | -1 |
| max | 1337 | 123 |
| variance | 352390.3 | 2966.8 |
| std_dev | 593.6247130974249 | 54.468339427597755 |
| count | 5 | 5 |
| missing | 0 | 0 |
Markdown 渲染结果如下
统计 | 号码1 | 数字2 |
---|---|---|
意思是 | 275.6 | 25.6 |
分钟 | -2 | -1 |
最大限度 | 1337 | 123 |
方差 | 352390.3 | 2966.8 |
标准差 | 593.6247130974249 | 54.468339427597755 |
数数 | 5 | 5 |
丢失的 | 0 | 0 |
最后,对包含单词“hitchhiker”的任何条目进行文本搜索:
tbl.create_search_index("words")
for match in tbl.search.words("hitchhiker"):
print(match)
印刷:
namespace(number1=-2, words='an interstellar hitchhiker can have.', number2=3)
解决方案 3:
如果需要 - 不使用 csv 模块读取 csv 文件:
rows = []
with open('test.csv') as f:
for line in f:
# strip whitespace
line = line.strip()
# separate the columns
line = line.split(',')
# save the line for use later
rows.append(line)
解决方案 4:
写入 CSV 文件
首先你需要导入 csv
例如:
import csv
with open('eggs.csv', 'wb') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=' ',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
解决方案 5:
读取带有标题的 CSV 文件到对象列表
将带有标题的 CSV 读入对象列表的示例,这可能更常见,因此我在下面提供了一个示例。本质上,我们有一个将数据放入其中的对象类型,每个用户的数据将进入一个包含“姓名、年龄、开始日期”的对象。然后我们将填充每个对象并按照从文件中读取的顺序将它们存储到列表中。
import csv
# We need a default object for each person
class Person:
def __init__(self, Name, Age, StartDate):
self.Name = Name
self.Age = Age
self.StartDate = StartDate
# We read in each row and assign it to an object then add that object to the overall list,
# and continue to do this for the whole list, and return the list
def read_csv_to_objects(file_path):
Persons = []
with open(file_path, 'r', newline='') as csvfile:
csv_reader = csv.DictReader(csvfile)
for row in csv_reader:
if row['Name']:
Each = Person(row['Name'], row['Age'], row['StartDate'])
Persons.append(Each)
return Persons
# Main calls the functions
file_path = "people.csv"
Persons = read_csv_to_objects(file_path)
for person in Persons:
print(f"Name: {person.Name} Age: {person.Age} StartDate: {person.StartDate}")
输出:
python3 import_people.py
Name: Bill Age: 21 StartDate: 10-10-2024
Name: Mike Age: 25 StartDate: 10-11-2013
Name: Vic Age: 44 StartDate: 9-11-2023
文件people.csv:
Name,Age,StartDate
Bill,21,10-10-2024
Mike,25,10-11-2013
Vic,44,9-11-2023
解决方案 6:
import csv
with open(fileLocation+'example.csv',newline='') as File: #the csv file is stored in a File object
reader=csv.reader(File) #csv.reader is used to read a file
for row in reader:
print(row)
解决方案 7:
使用 Pandas 读取 csv 文件
use pd.read_csv("D:\\sample.csv")
using only python :
fopen=open("D:\\sample.csv","r")
print(fopen.read())
创建并写入 csv 文件
下面的示例演示了如何创建和写入 csv 文件。要创建动态文件写入器,我们需要导入包 import csv,然后需要使用文件引用创建该文件的实例,例如:
with open("D:sample.csv","w",newline="") as file_writer
这里如果文件不存在所提到的文件目录那么python会在指定的目录中创建一个相同的文件,并w
表示写入,如果要读取文件则替换w
为r
或附加到现有文件a
。
newline=""
指定每次创建行时删除一个多余的空行,因此为了消除我们使用的空行newline=""
,使用列表创建一些字段名称(列名),如下所示:
fields=["Names","Age","Class"]
然后应用于 writer 实例,例如:
writer=csv.DictWriter(file_writer,fieldnames=fields)
这里使用字典编写器并分配列名,将列名写入我们使用的 csvwriter.writeheader()
并写入我们使用的值writer.writerow({"Names":"John","Age":20,"Class":"12A"})
,而写入文件值时必须使用字典方法传递,这里的键是列名,值是您各自的键值。
导入 csv:
with open("D:sample.csv","w",newline="") as file_writer:
fields=["Names","Age","Class"]
writer=csv.DictWriter(file_writer,fieldnames=fields)
writer.writeheader()
writer.writerow({"Names":"John","Age":21,"Class":"12A"})
解决方案 8:
我写了一个问题,问了类似的问题。因此,为了让所有内容都集中在一个地方,以下是我提出的一个非常快速而粗糙的解决方案。
此代码用于从一个 CSV 文件读取数据并写入另一个 CSV 文件。输出行的格式是固定的,我可以使用带有正确分隔符的 csv.write,但在这种情况下,我必须做额外的工作来指定空格。但它很好地展示了如何使用老旧的 print() 函数输出文本:
#! /usr/bin/env python3
def main():
parser = argparse.ArgumentParser(
description='',
usage="""myparser [-h] print this help and exit
""",
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument('-f', '--file',help='CSV input file', required=True)
args = parser.parse_args()
with open("output.file", "w") as outfile:
with open(args.file) as csvfile:
csv_reader = csv.reader(csvfile, delimiter=',')
line_count = 0
for row in csv_reader:
if line_count == 0:
line_count += 1
elif args.archive:
print(f'no:{row[0]}:{row[1]}::0:0:0:/bin/bash:0:0:{row[2]}:{row[3]}:{row[4]}:archive', file=outfile)
line_count += 1
return sys.exit(EXIT_SUCCESS)
if __name__ == '__main__':
main()
抱歉,造成了缩进。
此代码打开一个 CSV 文件进行读取,并使用 print() 函数写入格式化的字符串,如下所示:
no:Xoero:ToelAs:xtoelas:0:0:0:/bin/bash:0:0:y.r.j.pols@tue.nl:00311234567890:nl:archive
解决方案 9:
概述
csv模块读取和写入CSV 格式的文件对象。
需要导入模块:import csv
主要的csv模块对象是csv.reader和csv.writer对象。
还有字典包装对象 - csv.DictReader和csv.DictWriter - 它们返回并写入字典格式的数据。
对象实例化
读者和写者的启动都采用文件对象。
文件对象需要在初始化中实例化:newline=''
import csv
with open("my_file.csv", newline='') as csvfile:
reader_object = csv.reader(csvfile)
writer_object = csv.writer(csvfile)
读者
逐行迭代文件。
每行都以字符串列表的形式返回。
作家
将给定的列表写入文件。
功能:
writer_object.writerow(["a", "b", "c"])
writer_object.writerows([list_one, list_two, list_three])
csv.DictReader
将 csv 行元素解释为字典值。
句法:dict_reader = csv.DictReader(csvfile, fieldnames=none)
如果没有fieldnames
传递给读取器初始化:
csv 的第一行被解释为键。
第一行本身不会作为迭代行返回。
每个后续行都作为字典返回。
对于每个后续行,每个值的键是第一行中相应索引的元素。
如果将列表传递给fieldnames
:
该列表被解释为键。
第一行被解释为值。
对于每一行,每个值的键是列表中相应索引的元素
fieldnames
。
csv.DictWriter
概述:
csv.DictWriter对象将给定字典的值写入文件。
csv.DictWriter最初用包含字典键的强制列表实例化。
fieldnames
writerow()
当使用传递的字典调用其函数时,它会按照值的键在列表中的顺序将字典值写入文件fieldnames
。
初始化:dict_writer = csv.DictWriter(csvfile, fieldnames={keys_list})
功能:
dict_writer.writeheader()
dict_writer.writerow({dict})
dict_writer.writerows([dict_one, dict_two, dict_three])
扫码咨询,免费领取项目管理大礼包!