master
/ 8.3 文件的应用.ipynb

8.3 文件的应用.ipynb @masterview markup · raw · history · blame

Notebook

文件的应用

csv文件

CSV是文本文档,所以对文本进行读写的方法都适用于CSV格式文件的数据处理。而CSV格式的文件里的数据基本上都是由行和列构成的二维数据,可以使用列表嵌套的方法对其进行处理。

实例 9.5 读文件处理文件中的数据

文件5.7 score.csv 中数据如下,读取其中的数据并进行处理。

姓名,C语言,Java,Python,C#,C++ 罗明,95,96,85,63,91 朱佳,75,93,66,85,88 李思,86,76,96,93,67 郑君,88,98,76,90,89 王雪,99,96,91,88,86按要求完成以下操作: 1. 请读取文件中的数据,每行数据根据逗号切分为列表,输出二维列表。 2. 计算每位同学的总分附加到列表中各门课程成绩后面 3. 根据每名同学的总分进行降序排序输出 4. 将排序后的结果写入到新文件 “9.2 score_total.csv” 中
In [ ]:
# 读文件中的数据为二维列表

score_ls = []        # 创建空列表
with open('images/ch8/5.7 score.csv','r',encoding='utf-8') as fr:
    for line in fr:  # 遍历文件对象
    	score_ls.append(line.strip().split(','))  # 文件每行切分为一个列表,split()参数根据文件中的分隔符确定
print(score_ls)  

定义为函数,用列表推导式实现更简洁,类似问题只修改文件名和切分时使用的分隔符即可重用此代码。

In [ ]:
def read_file(filename):
    """接收文件名为参数,读取文件中的数据为二维列表,返回二维列表"""
    with open(filename, 'r', encoding='utf-8') as fr:
        score_ls = [x.strip().split(',') for x in fr]
    return score_ls


if __name__ == '__main__':
    score_lst = read_file('images/ch8/5.7 score.csv')
    print(score_lst)

为每位同学增加总成绩,可以将列表序号为0的元素score[0]拼接上['总分'],对剩余部分列表 score[1:] 进行遍历,每次得到一位同学的列表 x ,切片 x[1:] 为各门课的成绩,用map()函数将每个元素都 映射为整数,再用 sum() 函数对其进行求和并附加到列表中。

In [ ]:
def read_file(filename):
    """接收文件名为参数,读取文件中的数据为二维列表,返回二维列表"""
    with open(filename, 'r', encoding='utf-8') as fr:
        score_ls = [x.strip().split(',') for x in fr]
    return score_ls


def add_total(score_ls):
    """接收二维列表,增加总分,返回新的二维列表"""
    title = score_ls[0] + ['总分']  # 列表拼接,一维列表
    score_total = [title]          # 创建新列表,首元素为原列表标题行增加平均成绩
    for x in score_ls[1:]:         # 略过标题行进行遍历
        total = sum(map(int, x[1:]))          # 切取成绩部分映射为整数,计算总成绩
        score_total.append(x + [str(total)])  # 每个列表拼接字符型平均成绩
    return score_total


if __name__ == '__main__':
    score_lst = read_file('images/ch8/5.7 score.csv')
    print(add_total(score_lst))

将增加了总成绩的列表数据写入到文件中

In [ ]:
def read_file(filename):
    """接收文件名为参数,读取文件中的数据为二维列表,返回二维列表"""
    with open(filename, 'r', encoding='utf-8') as fr:
        score_ls = [x.strip().split(',') for x in fr]
    return score_ls


def add_total(score_ls):
    """接收二维列表,增加总分,返回新的二维列表"""
    title = score_ls[0] + ['总分']  # 列表拼接,一维列表
    score_total = [title]          # 创建新列表,首元素为原列表标题行增加平均成绩
    for x in score_ls[1:]:         # 略过标题行进行遍历
        total = sum(map(int, x[1:]))          # 切取成绩部分映射为整数,计算总成绩
        score_total.append(x + [str(total)])  # 每个列表拼接字符型平均成绩
    return score_total


def write_file(score_total, filename):
    """接收成绩二维列表和写入文件名的字符串,
    将二维列表中的数据分行写入文件,每个列表中的数据写为一行,用逗号分隔
    无返回值"""
    with open(filename, 'w', encoding='utf-8') as fw:  # 写模式打开文件
        for line in score_total:                       # 遍历二维列表
            fw.write(','.join(line) + '\n')   # 子列表元素用逗号拼接为字符串加换行符
            

if __name__ == '__main__':
    score_lst = read_file('images/ch8/5.7 score.csv')
    score_total_ls = add_total(score_lst)
    write_file(score_total_ls, 'score_total.csv')
    print(read_file('score_total.csv'))

练一练

修改实例9.4的程序,增加一个函数,可以获得文件中所有同学的名字,参考这个代码,获取并输出python课程的成绩的列表。

In [ ]:
def read_file(filename):
    """接收文件名为参数,读取文件中的数据为二维列表,返回二维列表"""
    with open(filename, 'r', encoding='utf-8') as fr:
        score_ls = [x.strip().split(',') for x in fr]
    return score_ls


def get_name(score_ls):
    """接收二维列表,返回全部学生名字的列表"""
    return [x[0] for x in score_ls[1:]]


if __name__ == '__main__':
    score_lst = read_file('images/ch8/5.7 score.csv')
    print(get_name(score_lst))

练一练

修改上面的程序,增加一个函数,可以获得文件中所有同学的名字,参考这个代码,获取并输出python课程的成绩的列表。
In [ ]:
# 获取并输出python课程的成绩的列表
def read_file(filename):
    """接收文件名为参数,读取文件中的数据为二维列表,返回二维列表"""
    with open(filename, 'r', encoding='utf-8') as fr:
        score_ls = [x.strip().split(',') for x in fr]
    return score_ls


def get_python(score_ls):
    """接收二维列表,返回全部学生python成绩的列表。
    列表中成绩应为整数
    """
    # 补充你的代码




if __name__ == '__main__':
    score_lst = read_file('images/ch8/5.7 score.csv')
    print(get_python(score_lst))
输出: [85, 66, 96, 76, 91]
In [ ]:
# 获取并输出python课程的成绩的列表
def read_file(filename):
    """接收文件名为参数,读取文件中的数据为二维列表,返回二维列表"""
    with open(filename, 'r', encoding='utf-8') as fr:
        score_ls = [x.strip().split(',') for x in fr]
    return score_ls


def get_python_avg(score_ls):
    """接收二维列表,返回全部学生python的平均成绩"""
    # 补充你的代码
    python = [int(x[3]) for x in score_ls[1:]]
    return sum(python) / len(python)



if __name__ == '__main__':
    score_lst = read_file('images/ch8/5.7 score.csv')
    print(get_python_avg(score_lst))
82.8

练一练

修改实例9.4的程序,获得并输出转置的列表提示: list(zip(*score_ls)) 可将二维列表中的数据行列转置,得到元素为元组的列表[['姓名', 'C语言', 'Java', 'Python', 'C#', 'C++'], ['罗明', '95', '96', '85', '63', '91'], ['朱佳', '75', '93', '66', '85', '88'], ['李思', '86', '76', '96', '93', '67'], ['郑君', '88', '98', '76', '90', '89'], ['王雪', '99', '96', '91', '88', '86']]

转为

[('姓名', '罗明', '朱佳', '李思', '郑君', '王雪'), ('C语言', '95', '75', '86', '88', '99'), ('Java', '96', '93', '76', '98', '96'), ('Python', '85', '66', '96', '76', '91'), ('C#', '63', '85', '93', '90', '88'), ('C++', '91', '88', '67', '89', '86')]
In [ ]:
def read_file(filename):
    """接收文件名为参数,读取文件中的数据为二维列表,返回行列转置后的二维列表"""
    # 补充你的代码

    
    

if __name__ == '__main__':
    score_lst = read_file('images/ch8/5.7 score.csv')
    print(score_lst)

练一练

附件文件成绩分析综合.csv 中记录了学生实验课的成绩,其中8次实验占总成绩的70%,作业成绩占总成绩的30%,请完成以下任务:

  1. 计算每位同学的总成绩
  2. 在平时成绩后增加总成绩,按总成绩降序排序,总成绩相同时按学号降序排序,写到文件“成绩分析汇总.csv”中
姓名,学号,实验一,实验二,实验三,实验四,实验五,实验六,实验七,实验八,作业成绩 叶灿,0121701100312,100,100,100,100,100,100,60,100,96 朱宇轩,0121701100702,100,100,100,100,100,100,90,100,99 陈一帆,0121701100730,100,100,100,100,50,100,80,75,89.25 王璐,0121701100733,100,100,100,100,100,100,100,100,100 ......
In [ ]:
# 此代码为读csv文件到列表中,参考此代码完成题目
def read_txt(filename):
    """读文件到二维列表"""
    with open(filename, encoding='utf-8') as f:
        return  [x.strip().split(',') for x in f]


if __name__ == '__main__':
    score = read_txt('images/ch8/成绩分析综合.csv')
    print(score)
In [ ]:
def read_csv(filename):
    """读文件到二维列表,精简代码"""
    # 补充你的代码
    


def add_total(score_ls):
    """接收包含成绩的二维列表,标题行增加“总成绩”列,计算总成绩并附加到列表中,
    返回增加了总成绩的二维列表。
    """
    # 补充你的代码
    


def write_file(total_score, filename):
    """接收成绩二维列表和写入文件名的字符串,将二维列表中的数据分行写入文件,
    每个列表中的数据写为一行,用逗号分隔,无返回值。
    """
    # 补充你的代码

    
            
if __name__ == '__main__':
    score_lst = read_csv('images/ch8/成绩分析综合.csv')  # 读文件到列表
    score_all = add_total(score_lst)  
    write_file(score_all, '成绩分析综合2.csv')  # 写入到'成绩分析综合2.csv'
    print(read_csv('成绩分析综合2.csv'))  # 再次调用读文件的函数,参数为新写入的文件名,查看是否写入成功

JSON文件

JSON的编码过程是将一个Python对象转为JSON格式数据,
主要使用json.dumps(obj)和json.dump(obj,fp)两个方法。

json.dumps(obj, *, ensure_ascii=True, indent=None, sort_keys=False) json.dump(obj, fp, *, ensure_ascii=True, indent=None, sort_keys=False)
方法 描述
json.dumps(obj) 将Python 数据类型obj对象编码成JSON数据,写入内存。
json.dump(obj,fp) 将Python 数据类型obj对象编码成JSON数据,写入磁盘文件对象fp中。

json 中默认ensure_ascii=True, 会将中文等非ASCII 字符转为unicode 编码(形如\uXXXX),设置ensure_ascii=False 可以禁止JSON 将中文转为unicode 编码,保持中文原样输出。
Python中的字典数据转为JSON 默认不排序。可设置sort_keys=True使转换结果按照字典升序排序(a-z)。
indent 参数可用来对JSON 数据进行格式化输出,默认值为None,不做格式化处理,可设一个大于0 的整数表示缩进量,例如indent=4。输出的数据被格式化之后,变得可读性更好。

JSON的解码过程是将JSON格式数据转为Python对象,Python 的原始类型与JSON类型会相互转换。
主要使用json.loads(s)和json.load(fp)两个方法。

json.load(fp) json.loads(s)
方法 描述
json.loads(s) 将字符串s中的JSON数据解码为Python 数据类型,其他格式数据会转为unicode格式。
json.load(fp) 将磁盘文件对象fp中的JSON数据解码为Python 数据类型,其他格式数据会转为unicode格式。

将csv文件"成绩分析综合.csv"转为json文件

1. 将文件读为二维列表 2. 遍历二维列表序号1以后的元素 2.1 用zip()将二维列表序号为 0 的子列表分别与后续的子列表组合并用dict()转为字典类型 3. 用dumps()将字典转为json格式数据写入json文件 读"成绩分析综合.json"为列表1. 读文件创建文件对象fp 1.1 用json.load(fp)将文件内中的数据读为python数据类型 2. 返回读取的结果
In [ ]:
import json


def read_csv(filename):
    """读文件到二维列表,返回二维列表"""
    with open(filename, "r", encoding='utf-8') as f:
        return [x.strip().split(',') for x in f]


def to_json(score_ls):
    """将二维列表标题行的元素与子列表中的元素一一组合,
    禁止JSON 将中文转为unicode 编码,保持中文原样输出。
    对JSON 数据进行格式化输出,缩进4个字符,
    返回json格式数据"""
    score_dic = []
    for i in range(1, len(score_ls)):
        score_dic.append(dict(zip(score_ls[0], score_ls[i])))
    return json.dumps(score_dic, ensure_ascii=False, indent=4)


def write_to_json(score_ls):
    """将二维列表标题行的元素与子列表中的元素一一组合,
    禁止JSON 将中文转为unicode 编码,保持中文原样输出。
    对JSON 数据进行格式化输出,缩进4个字符,
    写入json格式文件"""
    score_dic = []
    for i in range(1, len(score_ls)):
        score_dic.append(dict(zip(score_ls[0], score_ls[i])))
    with open('成绩分析综合.json','w',encoding='utf-8') as score_json:
        json.dump(score_dic,score_json, ensure_ascii=False, indent=4)


def read_json_to_ls(filename):
    """读json文件,返回元素为字典类型的列表"""
    with open(filename, "r", encoding='utf8') as f:
        score_dic_ls = json.load(f)
    return score_dic_ls


if __name__ == '__main__':
    score_lst = read_csv('images/ch8/成绩分析综合.csv')
    # print(to_json(score_lst))
    write_to_json(score_lst)
    print(read_json_to_ls('成绩分析综合.json'))
In [ ]:
def read_json(filename):
    """读json文件,以字符串形式输出,查看写入文件的格式"""
    with open(filename, "r", encoding='utf8') as f:
        print(f.read())


if __name__ == '__main__':
    read_json('成绩分析综合.json')

借用eval()实现json转csv

eval()可以将字符串转为python数据类型,所以可以先用read()将json文件内容读取为字符串,再用eval()转为列表,再转csv文件

In [ ]:
with open('成绩分析综合.json',encoding='utf-8') as fr:
    txt = fr.read()                          # txt为字符串

txt_py = eval(txt)                           # txt_py为元素为字典的列表
title = list(txt_py[0].keys())               # title为标题列表
score = [list(i.values()) for i in txt_py]   # score为值的列表
score_ls = [title]+score                     # score_ls为标题+值的列表

with open('成绩分析综合.csv','w',encoding='utf-8') as fw:
    for lst in score_ls:                     # 遍历列表
        fw.write(','.join(lst)+'\n')          # 将列表用逗号拼接为字符串并写入文件

os库常用方法

方法 描述
os.getcwd() 获取当前工作路径
os.chdir(path) 将当前工作路径修改为path,如os.chdir(r'c:\Users')
os.path.exist(name) 判断name文件夹或文件是否存在,存在返回True,否则返回False
os.mkdir(pathname) 新建一个名为pathname的文件夹
os.rmdir(pathname) 删除空文件夹pathname,文件夹不为空则报OSError错误
os.path.isdir(path) 判断path是否是文件夹,是则返回True,否则返回False
os.path.getsize(file) 文件file存在,返回其大小(byte为单位),不存在则报错
os.remove(filename) 删除文件 filename,文件不存在则报错
os.path.isfile(filename) 返回filename是否是文件,是返回True,否则返回False
os.listdir(path) 以列表形式返回path路径下的所有文件名,不包括子路径中的文件名
os.walk(path) 返回类型为生成器,包含数据为若干包含文件和文件夹名的元组数据
In [ ]:
# getcwd() 获取当前工作目录

import os

result = os.getcwd() 
print(result)
In [ ]:
import os


result = os.listdir('/home/jovyan/work')
print(result)
In [ ]:
import numpy as np

data = np.genfromtxt('images/ch8/成绩分析综合.csv',delimiter=',',encoding='utf-8',dtype=str)
# 数据的标题行中有#,其后面的内容默认会被当成注释而忽略掉,导致标题行与数据行的列数不同而出错,可以用comments标明注释符
print(data)
In [ ]:
import numpy as np

data = np.genfromtxt('images/ch8/5.7 score.csv',delimiter=',',encoding='utf-8',dtype=str,comments=None)
# 数据的标题行中有#,其后面的内容默认会被当成注释而忽略掉,导致标题行与数据行的列数不同而出错,可以用comments标明注释符
print(data)
In [ ]: