当前位置:   article > 正文

79. 将3个csv文件汇总成一个csv文件_多个csv文件合并计算

多个csv文件合并计算

79. 将3个csv文件汇总成一个csv文件

1. 新建1个CSV文件

已知5个学生的学号和5个科目的成绩如下:

data = [
    ['01', 100, 100, 100, 100],
    ['02', 90, 90, 90, 90],
    ['03', 80, 80, 80, 80],
    ['04', 70, 70, 70, 70],
    ['05', 60, 60, 60, 60]
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
'
运行

我这里用嵌套列表表示学生的学号和成绩。

【目标任务】

  1. 计算每位学生的总分,连同各科成绩,一起写入1班成绩.csv文件。

  2. 将CSV文件的首行设置为标题行,字段名称分别为学号, 语文, 数学, 英语, python, 总分

  3. 用代码输出写入的内容。

【准备工作】

  1. 在电脑D盘新建一个【79】文件夹。

  2. 用VScode编辑器打开【79】文件夹。

  3. 在【79】文件夹中新建一个79.py文件。

  4. 大家在79.py文件中编写代码。

【参考答案】

# 导入os 模块,用于创建文件目录
import os
# 导入 csv 模块,用于操作CSV文件
import csv

# mkdir作用是创建目录,作用等同于新建一个【成绩汇总】文件夹
# 括号里的内容是madir函数的参数
# 这里的参数值为相对路径
os.mkdir("成绩汇总")

# 用字典存储要写入CSV文件的信息
dict1 = {'学号': '01', '语文': '100','数学': '100','英文': '100','Python': '100','总分': '400'}
dict2 = {'学号': '02', '语文': '90','数学': '90','英文': '90','Python': '90','总分': '360'}
dict3 = {'学号': '03', '语文': '80','数学': '80','英文': '80','Python': '80','总分': '320'}
dict4 = {'学号': '04', '语文': '70','数学': '70','英文':  '70','Python':  '70','总分': '280'}
dict5 = {'学号': '05', '语文': '60','数学': '60','英文': '60','Python': '60','总分': '240'}

# 设置文件的表头,即列名
header = ['学号', '语文', '数学','英文','Python','总分']

# 文件的相对路径
file_path = r'成绩汇总/1班成绩.csv'

# 以自动关闭文件的方式创建文件对象
with open(file_path, 'a', encoding='utf-8', newline="") as f:
    
    # 实例化类 DictWriter(),得到 DictWriter 对象
    dw = csv.DictWriter(f, fieldnames=header)

    # writeheader方法写入文件的表头
    dw.writeheader()
    
    # writerows方法一次性写入多行
    # 方法的参数为列表
    dw.writerows([dict1, dict2, dict3, dict4, dict5])

with open(file_path, 'r', encoding='utf-8') as f:
    # 实例化类 DictReader,得到DictReader对象
    # 以字典的形式获取 csv 文件信息
    dr = csv.DictReader(f)  
    # 读取表头
    print(dr.fieldnames)
    # 打印字典的数据
    for row in dr:
        print(row)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
'
运行

【终端输出】

['学号', '语文', '数学', '英文', 'Python', '总分']
{'学号': '01', '语文': '100', '数学': '100', '英文': '100', 'Python': '100', '总分': '400'}
{'学号': '02', '语文': '90', '数学': '90', '英文': '90', 'Python': '90', '总分': '360'}
{'学号': '03', '语文': '80', '数学': '80', '英文': '80', 'Python': '80', '总分': '320'}
{'学号': '04', '语文': '70', '数学': '70', '英文': '70', 'Python': '70', '总分': '280'}
{'学号': '05', '语文': '60', '数学': '60', '英文': '60', 'Python': '60', '总分': '240'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

with open 函数的mode参数:

在这里插入图片描述

当mode=a的时候,表示以追加方式向csv文件写入内容,追加的意思就是保留文件原有的内容。

当mode=r的时候,表示以只读方式打开文件。

运行代码后,打开1班成绩.csv文件如下图所示:

【用excle打开】

在这里插入图片描述

【用记事本打开】

在这里插入图片描述

2. 再新建2个csv文件

【目标任务】

  1. 参照上面的步骤再新建2个csv文件,分别命名为2班成绩.csv3班成绩.csv

  2. 向每个csv文件写入5个学生的成绩,注意字段名称和1班成绩.csv要一致。

  3. 将3个csv文件的内容汇总到一个csv文件中,命名为一年级成绩汇总表.csv

【创建文件写入内容的代码】

# 导入 csv 模块,用于操作CSV文件
import csv

# 用字典存储要写入CSV文件的信息
dict6 = {'学号': '06', '语文': '100','数学': '100','英文': '100','Python': '100','总分': '400'}
dict7 = {'学号': '07', '语文': '90','数学': '90','英文': '90','Python': '90','总分': '360'}
dict8 = {'学号': '08', '语文': '80','数学': '80','英文': '80','Python': '80','总分': '320'}
dict9 = {'学号': '09', '语文': '70','数学': '70','英文':  '70','Python':  '70','总分': '280'}
dict10 = {'学号': '10', '语文': '60','数学': '60','英文': '60','Python': '60','总分': '240'}

dict11 = {'学号': '11', '语文': '100','数学': '100','英文': '100','Python': '100','总分': '400'}
dict12 = {'学号': '12', '语文': '90','数学': '90','英文': '90','Python': '90','总分': '360'}
dict13 = {'学号': '13', '语文': '80','数学': '80','英文': '80','Python': '80','总分': '320'}
dict14 = {'学号': '14', '语文': '70','数学': '70','英文':  '70','Python':  '70','总分': '280'}
dict15 = {'学号': '15', '语文': '60','数学': '60','英文': '60','Python': '60','总分': '240'}

# 设置文件的表头,即列名
header = ['学号', '语文', '数学','英文','Python','总分']

# 文件的相对路径
file_path2 = r'成绩汇总/2班成绩.csv'

# 以自动关闭文件的方式创建文件对象
with open(file_path2, 'a', encoding='utf-8', newline="") as f:
    
    # 实例化类 DictWriter(),得到 DictWriter 对象
    dw = csv.DictWriter(f, fieldnames=header)

    # 写入文件的表头
    dw.writeheader()    
    # writerows多行写入
    dw.writerows([dict6, dict7, dict8, dict9, dict10])

# 文件的相对路径
file_path3 = r'成绩汇总/3班成绩.csv'

# 以自动关闭文件的方式创建文件对象
with open(file_path3, 'a', encoding='utf-8', newline="") as f:
    
    # 实例化类 DictWriter(),得到 DictWriter 对象
    dw = csv.DictWriter(f, fieldnames=header)

    # 写入文件的表头
    dw.writeheader()    
    # writerows多行写入
    dw.writerows([dict11, dict12, dict13, dict14, dict15])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

上面的代码没什么难度,就是修改几个参数即可。

  1. 修改相对路径:file_path2 = r'成绩汇总/2班成绩.csv'

  2. 修改with open 的路径参数file_path2

  3. 修改多行写入的参数dw.writerows([dict6, dict7, dict8, dict9, dict10])

运行上述代码,我们成功新建了2班成绩.csv3班成绩.csv2个文件。

将3个csv文件汇总成一个csv文件,这是本节要学习的重点:

# 导入 os 模块
import os
# 导入 csv 模块
import csv

# 设置文件夹路径
folder_path1 = "成绩汇总/" # 相对路径                  
folder_path2 = r"D:\安迪笔记\1.基础语法\79\成绩汇总/"  # 绝对路径

# 获取要汇总的文件的文件名
file_list = os.listdir(folder_path1)

# 设置文件的表头,即列名
header = ['学号', '语文', '数学','英文','Python','总分']

# 设置一个空列表
rows = []

# 遍历所有文件
for file in file_list:
    # 通过文件夹拼接文件名的方式,获取文件路径
    file_path = folder_path1 + file

    # 以自动关闭的方式打开文件
    with open(file_path, 'r', encoding='utf-8') as f:
        
        # 以字典的形式获取 csv 文件信息
        file_dict = csv.DictReader(f)

        # 打印字典的数据
        for row in file_dict:
            print(row)
            # 将读取出来的行数据,循环写入 rows 列表中
            rows.append(row)

# 以末尾添加的方式写入文件
with open('成绩汇总/一年级成绩汇总表.csv', 'w', encoding='utf-8',newline="") as file:

    # 实例化类 DictWriter() 得到 DictWriter 对象
    dict_write = csv.DictWriter(file, fieldnames=header)

    # 写入文件的表头
    dict_write.writeheader()

    # 写入文件的多行内容
    dict_write.writerows(rows)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

【终端输出】

{'学号': '01', '语文': '100', '数学': '100', '英文': '100', 'Python': '100', '总分': '400'}
{'学号': '02', '语文': '90', '数学': '90', '英文': '90', 'Python': '90', '总分': '360'}
{'学号': '03', '语文': '80', '数学': '80', '英文': '80', 'Python': '80', '总分': '320'}
{'学号': '04', '语文': '70', '数学': '70', '英文': '70', 'Python': '70', '总分': '280'}
{'学号': '05', '语文': '60', '数学': '60', '英文': '60', 'Python': '60', '总分': '240'}
{'学号': '06', '语文': '100', '数学': '100', '英文': '100', 'Python': '100', '总分': '400'}
{'学号': '07', '语文': '90', '数学': '90', '英文': '90', 'Python': '90', '总分': '360'}
{'学号': '08', '语文': '80', '数学': '80', '英文': '80', 'Python': '80', '总分': '320'}
{'学号': '09', '语文': '70', '数学': '70', '英文': '70', 'Python': '70', '总分': '280'}
{'学号': '10', '语文': '60', '数学': '60', '英文': '60', 'Python': '60', '总分': '240'}
{'学号': '11', '语文': '100', '数学': '100', '英文': '100', 'Python': '100', '总分': '400'}
{'学号': '12', '语文': '90', '数学': '90', '英文': '90', 'Python': '90', '总分': '360'}
{'学号': '13', '语文': '80', '数学': '80', '英文': '80', 'Python': '80', '总分': '320'}
{'学号': '14', '语文': '70', '数学': '70', '英文': '70', 'Python': '70', '总分': '280'}
{'学号': '15', '语文': '60', '数学': '60', '英文': '60', 'Python': '60', '总分': '240'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

【语法解析】

# 导入 os 模块
import os
# 导入 csv 模块
import csv
  • 1
  • 2
  • 3
  • 4
'
运行

导入os模块用来操作文件目录,这里用来获取文件的路径。

导入csv模块用来操作csv文件。

# 设置文件夹路径
folder_path1 = "成绩汇总/" # 相对路径                  
folder_path2 = "D:\安迪笔记\1.基础语法\79\成绩汇总/"  # 绝对路径
  • 1
  • 2
  • 3
'
运行

folder[ˈfəʊldə]:文件夹。

path [pɑːθ]:路径。

folder_path是变量名,用来存储文件夹的路径。

这里我写了2个路径,是为了提醒大家这个变量表示路径。

【温馨提示】

成绩汇总/

大家注意我在路径的最后多添加了一个/,这是后面和文件名进行连接,生成csv文件路径用的。

# 获取要汇总的文件的文件名
file_list = os.listdir(folder_path1)
  • 1
  • 2
  1. 调用模块的函数语法:模块名.函数名

  2. os模块名

  3. listdir函数名。

listdir 是 list directory 的缩写,译为目录的列表。

list [lɪst]:列表。

directory [dəˈrektəri]:目录。

os.listdir( )返回指定文件夹下,文件或文件夹名字的列表。

注意返回的数据类型是列表。

# 导入 os 模块
import os

# 获取要汇总的文件的文件名
file_list = os.listdir(folder_path1)
print(type(file_list))
print(file_list)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

【终端输出】

<class 'list'>
['1班成绩.csv', '2班成绩.csv', '3班成绩.csv']
  • 1
  • 2

因为要返回的数据是列表,因此变量名我起了file_list,文件列表的意思。

os.listdir(folder_path1)返回folder_path1文件夹中的文件列表。

folder_path1文件夹即成绩汇总文件夹。

成绩汇总文件夹中有3个文件,因此返回该3个文件的列表。

# 设置文件的表头,即列名
header = ['学号', '语文', '数学','英文','Python','总分']
# 设置一个空列表
rows = []
  • 1
  • 2
  • 3
  • 4
'
运行

空列表是后面存储循环到的数据用的。

# 遍历所有文件
for file in file_list:
    # 通过文件夹拼接文件名的方式,获取文件路径
    file_path = folder_path1 + file
    print(file_path)
  • 1
  • 2
  • 3
  • 4
  • 5

【终端输出】

成绩汇总/1班成绩.csv
成绩汇总/2班成绩.csv
成绩汇总/3班成绩.csv
  • 1
  • 2
  • 3

上面的代码实现的功能是将文件夹名称和文件名名称进行拼接,得到要汇总的文件的相对路径。

for file in file_list:for循环遍历file_list列表。

我们之前用os.listdir输出的file_list列表如下:

file_list=['1班成绩.csv', '2班成绩.csv', '3班成绩.csv']
  • 1
'
运行

那file就依次从列表中file_list取值。

【第一次取值】

file第一次取到的值为'1班成绩.csv',即file='1班成绩.csv'

# 通过文件夹拼接文件名的方式,获取文件路径
file_path = folder_path1 + file
  • 1
  • 2

这里是一个路径的拼接:

folder_path1 = "成绩汇总/" # 相对路径 
  • 1
'
运行
file='1班成绩.csv'
  • 1
'
运行

此时

file_path="成绩汇总/1班成绩.csv"
  • 1
'
运行

同理:

for循环第1次取值:file='1班成绩.csv'file_path="成绩汇总/1班成绩.csv"

for循环第2次取值:file='2班成绩.csv'file_path="成绩汇总/2班成绩.csv"

for循环第3次取值:file='3班成绩.csv'file_path="成绩汇总/3班成绩.csv"

我们得到的file_path就是我们刚才创建的3个csv文件的相对路径。

# 以自动关闭的方式打开文件
with open(file_path, 'r', encoding='utf-8') as f:        
    # 以字典的形式获取 csv 文件信息
    dr = csv.DictReader(f)
  • 1
  • 2
  • 3
  • 4

实例化类创建对象语法

对象名=类名( )

  1. 对象名是dr,就是一个变量名字,大家根据自己的喜好起名。因为实例化DictReader类后得到的是一个DictReader对象,因此我起了一个dr的变量名。

  2. csv是模块名。DictReader类是CSV模块里的,因此我们需要加上csv模块名。表示实例化CSV模块中的DictReader类。

  3. DictReader是类名。

  4. f是with open语句创建的文件对象。

实例化类 DictReader后得到一个DictReader对象。

【温馨提示】

with open是for循环的代码块,注意这里要有4个空格的缩进。

这里是要先读取1班成绩.csv,再读取2班成绩.csv,最后再读取3班成绩.csv

程序就是用for循环来控制依次打开文件读取内容的。

这里要特别注意必须有缩进。

# 打印字典的数据
for row in dr:
    print(row)
    # 将读取出来的行数据,循环写入 rows 列表中
    rows.append(row)
  • 1
  • 2
  • 3
  • 4
  • 5

我们得到DictReader对象后,我们再用for循环从对象中依次取值。

row [rəʊ]:行。

row变量名,存储每次从dr中取到的值。因为每次取到一行,因此我起了变量名row。

取到的值是一个字典,然后我们将取到的字典添加到我们最开始新建的空列表中。

取到的值为什么是字典呢?

因为CSV模块DictReader类的作用就是以字典的形式读取内容。

rows.append(row)
  • 1

append( )函数向列表增加元素。

append [əˈpend]增加,附加。

列表名.append(要增加的元素)

向列表rows中添加row。

每循环一次添加一个row。

这里的输出print(row)的循环是内循环。

我们创建的csv文件有5个字典,则该循环执行5次。

该循环执行5次之后,程序返回到外循环。

第2次外循环程序取到第2个csv文件,再来一次内循环输出5个字典。

然后程序返回到外循环,第3次外循环程序取到第3个csv文件,然后继续内循环输出字典。

外循环的列表中只有3个元素,因此外循环执行了3次,循环彻底结束,继续往下走。

【总结】

这部分代码外循环执行了3次,每次外循环时内循环执行了5次。

上面的代码将我们要写入的内容全部汇总到rows列表里了,那接下来我们就可以用DictWriter将列表的值写入一个csv文件了。

# 以末尾添加的方式写入文件
with open('成绩汇总/一年级成绩汇总表.csv', 'w', encoding='utf-8',newline="") as f:

    # 实例化类 DictWriter() 得到 DictWriter 对象
    dw = csv.DictWriter(f, fieldnames=header)

    # 写入文件的表头
    dw.writeheader()

    # 写入文件的多行内容
    dw.writerows(rows)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这部分内容大家应该很熟了,这里不做赘述。

【之前的写入代码】

# 写入文件的多行内容
dw.writerow([dict1,dict2,dict3,dict4,dict5])
  • 1
  • 2

【现在的写入代码】

# 写入文件的多行内容
dw.writerows(rows)
  • 1
  • 2

这里的rows本质如下:

rows=[
    dict1,dict2,dict3,dict4,dict5,
    dict6,dict7,dict8,dict9,dict10,
    dict11,dict12,dict13,dict14,dict15
    ]
  • 1
  • 2
  • 3
  • 4
  • 5

writerows方法的参数都是列表。

要写入的内容的本质都是字典。

3. 思路解析

【人工操作步骤】

  1. 手动打开3个csv文件。

  2. 新建一个一年级成绩汇总表.csv文件用来汇总。

  3. 将3个csv文件的内容复制后粘贴到一年级成绩汇总表.csv文件。

【代码操作步骤】

  1. 生成3个csv文件的路径。

这个路径我用文件夹路径拼接文件名来生成。

  1. 读取3个csv文件的内容,将每次读取到的内容添加到一个列表里。

  2. 最后将列表中的内容一次性写入最终的csv文件。

其实手动和代码的原理是一样的。

只是手动就是一个全选粘贴复制的过程。

但代码不一样的地方在于你要先把读取到的内容复制到一个列表里,然后再进行写入。

就像扫描一样,它是要一行一行的扫描进去的。

4. for循环解析

本节的代码没有什么难点。

初学者最容易报错的就是for循环的缩进问题。

在这里插入图片描述

5. 总结

# 导入 os 模块
import os
# 导入 csv 模块
import csv

# 设置文件夹路径
folder_path1 = "成绩汇总/" # 相对路径                  
folder_path2 = r"D:\安迪笔记\1.基础语法\79\成绩汇总/"  # 绝对路径

# 获取要汇总的文件的文件名
file_list = os.listdir(folder_path1)

# 设置文件的表头,即列名
header = ['学号', '语文', '数学','英文','Python','总分']

# 设置一个空列表
rows = []

# 遍历所有文件
for file in file_list:
    # 通过文件夹拼接文件名的方式,获取文件路径
    file_path = folder_path1 + file

    # 以自动关闭的方式打开文件
    with open(file_path, 'r', encoding='utf-8') as f:
        
        # 以字典的形式获取 csv 文件信息
        file_dict = csv.DictReader(f)

        # 打印字典的数据
        for row in file_dict:
            print(row)
            # 将读取出来的行数据,循环写入 rows 列表中
            rows.append(row)

# 以末尾添加的方式写入文件
with open('成绩汇总/二年级成绩汇总表.csv', 'w', encoding='utf-8',newline="") as file:

    # 实例化类 DictWriter() 得到 DictWriter 对象
    dict_write = csv.DictWriter(file, fieldnames=header)

    # 写入文件的表头
    dict_write.writeheader()

    # 写入文件的多行内容
    dict_write.writerows(rows)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

【终端输出】

{'学号': '01', '语文': '100', '数学': '100', '英文': '100', 'Python': '100', '总分': '400'}
{'学号': '02', '语文': '90', '数学': '90', '英文': '90', 'Python': '90', '总分': '360'}
{'学号': '03', '语文': '80', '数学': '80', '英文': '80', 'Python': '80', '总分': '320'}
{'学号': '04', '语文': '70', '数学': '70', '英文': '70', 'Python': '70', '总分': '280'}
{'学号': '05', '语文': '60', '数学': '60', '英文': '60', 'Python': '60', '总分': '240'}
{'学号': '06', '语文': '100', '数学': '100', '英文': '100', 'Python': '100', '总分': '400'}
{'学号': '07', '语文': '90', '数学': '90', '英文': '90', 'Python': '90', '总分': '360'}
{'学号': '08', '语文': '80', '数学': '80', '英文': '80', 'Python': '80', '总分': '320'}
{'学号': '09', '语文': '70', '数学': '70', '英文': '70', 'Python': '70', '总分': '280'}
{'学号': '10', '语文': '60', '数学': '60', '英文': '60', 'Python': '60', '总分': '240'}
{'学号': '11', '语文': '100', '数学': '100', '英文': '100', 'Python': '100', '总分': '400'}
{'学号': '12', '语文': '90', '数学': '90', '英文': '90', 'Python': '90', '总分': '360'}
{'学号': '13', '语文': '80', '数学': '80', '英文': '80', 'Python': '80', '总分': '320'}
{'学号': '14', '语文': '70', '数学': '70', '英文': '70', 'Python': '70', '总分': '280'}
{'学号': '15', '语文': '60', '数学': '60', '英文': '60', 'Python': '60', '总分': '240'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/940698
推荐阅读
相关标签
  

闽ICP备14008679号