PythonforResearch | 1_文件操作

时间:2022-07-23
本文章向大家介绍PythonforResearch | 1_文件操作,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

创建日期: 20200805 14:20 上次修改: 20200805 15:10 Python 版本: Python 3.7

项目介绍:一直想写一份适合经济学等社科背景、学术科研向的 Python 教程。因为学经济学的多少会对 Stata 有所了解,有一些写代码命令的经历,这份教程应该:

  • 简洁好理解,花最少的时间了解 Python 的核心用法;
  • 实用易操作,最好是能够看完上手即用。

在构思了一段时间之后,偶然发现 Ties de Kok 的 Get started with Python for research tutorial项目已经搭建出了我想要的框架。于是打算在这个项目的基础上进行完善,首先将其主要内容“汉化”成中文,之后对用法进行扩充、加入典型用法和案例。

原作者简介:Ties de Kok (Personal Website)为华盛顿大学福斯特商学院的助理教授,他专注于将计算机科学与实证会计研究相结合,研究兴趣是财务会计、资本市场、计算机科学、自然语言处理和经验管理会计。

往期目录:

PythonforResearch | 0_语法基础

简介

使用 Pytnon 可以打开多种格式的数据文件,本节仅介绍一些亲测比较好用的方式。后文提及的所有数据都在data文件夹内,生成这些数据的代码在文末。

导入库

import os
import pandas as pd
from glob import glob
import json

为了方便,下面这种引用方式可以使用join代替os.path.join

from os.path import join

文件夹建立索引

将文件夹建立索引对打开文件非常有用,例如要要遍历文件夹中的所有文件,当然有多种实现方式,但是下面将主要介绍os.listdir,globos.walk

定义路径

示例中所需数据都在data文件夹中,所以首先如下定义路径:

data_path = join(os.getcwd(), 'data')

获取根目录下所有文件

注意:这种方式会忽略子文件夹中的文件

filenames = os.listdir(data_path)
filepaths = [join(data_path, filename) for filename in filenames]
filepaths[:2] # show first two items
['D:\PyStaData\Python\Python_for_Research\PythonforResearch\data\311-service-requests.csv',
 'D:\PyStaData\Python\Python_for_Research\PythonforResearch\data\auto_df.csv']

使用glob,因为它直接允许包含路径名匹配。例如,如果只想要 Excel.xlsx文件:

glob(join(data_path, '*.xlsx'))
['D:\PyStaData\Python\Python_for_Research\PythonforResearch\data\excel_sample.xlsx']

获取所有文件(包含子文件夹)

如果文件夹包含多个级别,则需要使用`os.walk()`或`glob`:
  File "<ipython-input-23-62a5d92e9698>", line 1
    如果文件夹包含多个级别,则需要使用`os.walk()`或`glob`:
                    ^
SyntaxError: invalid character in identifier
folder = os.getcwd()
filepaths = []
for root,dirs,files in os.walk(folder):
    for i in files:
        filepaths.append(join(root,i))
filepaths[:2]
['D:\PyStaData\Python\Python_for_Research\PythonforResearch\0_语法基础.ipynb',
 'D:\PyStaData\Python\Python_for_Research\PythonforResearch\1_文件打开与保存.ipynb']

使用 glob会产生更清晰的代码,但是会更晦涩:

filepaths_glob = glob(join(folder, '**/*'), recursive=True)
filepaths_glob[:2]
['D:\PyStaData\Python\Python_for_Research\PythonforResearch\0_语法基础.ipynb',
 'D:\PyStaData\Python\Python_for_Research\PythonforResearch\1_文件打开与保存.ipynb']

文本文件

使用 Python 默认库,打开文件的四种模式:

w -> write only r -> read only w+ -> read and write + completely overwrite file a+ -> read and write + append at the bottom

打开文件

with open(join(data_path, 'text_sample.txt'), 'r') as file:
    file_content = file.read()
print(file_content)
Learning Python is great.
Good luck!

写入文件

with open(join(data_path, 'text_sample.txt'), 'w+') as file:
    file.write('Learning Python is great. nGood luck!')

除了使用with,也可以使用openclose打开文件:

f = open(join(data_path, 'text_sample.txt'), 'r')
file_content = f.read()
f.close()

使用open记得最后一定要.close(),否则会因为文件被占用而报错。因此,推荐使用with方法,它会自动关闭文件。

文件索引中循环

text_files = glob(join(data_path, '*.txt'))
text_list = []

for i in text_files:
    with open(i, 'r') as f:
        text_list.append(f.read())
text_list
['Content of new file. nHi there!nNew line',
 'Learning Python is great. nGood luck!']

Excel 文件

有多种方式打开 Excel、csv、Stata 和 SAS 数据集,但这里主要介绍使用 Pandas 库。

打开 Excel 文件

excel_file = pd.read_excel(join(data_path, 'excel_sample.xlsx'))

read_excel()函数具有许多选项,可以参阅:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_excel.html

提示:有时候需要指定编码类型来防止编码报错,例如:,encoding='utf-8'

## 保存Excel文件
excel_file.to_excel(join(data_path, 'excel_sample.xlsx'))

这将保存 Pandas 的数据框(DataFrame)对象,请参见数据处理文件: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_excel.html

CSV 文件

打开 CSV 文件

csv_file = pd.read_csv(join(data_path, 'csv_sample.csv'), sep=',')

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_csv.html

保存 CSV 文件

csv_file.to_csv(join(data_path, 'csv_sample.csv'), sep=',')

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_csv.html

Stata 文件

打开 Stata 数据

stata_file = pd.read_stata(join(data_path, 'stata_sample.dta'))

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_stata.html

保存 Stata 数据

stata_file.to_stata(join(data_path, 'stata_sample.dta'))

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_stata.html

提示:请确保更新至适用于新 Stata 版本的最新版本的 Pandas。

SAS 文件

Pandas 只能打开 SAS 文件,不能写入数据:

sas_file = pd.read_sas(r'C:file.sas7bdat', format='sas7bdat')

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_sas.html 此功能在大多数情况下都有效,但是带有文本的文件可能会很难修复编码错误。

Json 文件

使用 Pandas 库

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_json.html

*提示:*路径也可以是链接(url)

将 JSON 读入为 dataframe

json_df = pd.read_json(join(data_path, 'json_sample.json'))

将 dataframe 保存为 JSON

json_df.to_json(join(data_path, 'json_sample.json'))

使用 JSON

读取 JSON

with open(join(data_path, 'json_sample.json'), 'r') as f:
    json_data = json.load(f)

写入 Json

with open(join(data_path, 'json_sample.json'), 'w') as f:
    json.dump(json_data, f)

生成示例数据文件的代码

带有随机数的字典:

raw_data = {'foreign':{1:'Domestic',2:'Domestic',3:'Domestic',6:'Domestic',7:'Domestic',8:'Domestic',9:'Domestic',14:'Domestic',21:'Domestic',23:'Domestic',24:'Domestic',30:'Domestic',31:'Domestic',33:'Domestic',37:'Domestic',38:'Domestic',43:'Domestic',48:'Domestic',50:'Domestic',51:'Domestic',53:'Foreign',56:'Foreign',57:'Foreign',66:'Foreign',70:'Foreign'},
            'make':{1:'AMCPacer',2:'AMCSpirit',3:'BuickCentury',6:'BuickOpel',7:'BuickRegal',8:'BuickRiviera',9:'BuickSkylark',14:'Chev.Impala',21:'DodgeMagnum',23:'FordFiesta',24:'FordMustang',30:'Merc.Marquis',31:'Merc.Monarch',33:'Merc.Zephyr',37:'OldsDelta88',38:'OldsOmega',43:'Plym.Horizon',48:'Pont.GrandPrix',50:'Pont.Phoenix',51:'Pont.Sunbird',53:'AudiFox',56:'Datsun210',57:'Datsun510',66:'ToyotaCelica',70:'VWDiesel'},
            'price': {1:4749,2:3799,3:4816,6:4453,7:5189,8:10372,9:4082,14:5705,21:5886,23:4389,24:4187,30:6165,31:4516,33:3291,37:4890,38:4181,43:4482,48:5222,50:4424,51:4172,53:6295,56:4589,57:5079,66:5899,70:5397},
            'weight':{1:3350,2:2640,3:3250,6:2230,7:3280,8:3880,9:3400,14:3690,21:3600,23:1800,24:2650,30:3720,31:3370,33:2830,37:3690,38:3370,43:2200,48:3210,50:3420,51:2690,53:2070,56:2020,57:2280,66:2410,70:2040}}

将字典转换为 Pandas 的 dataframe,便于保存:

df_data = pd.DataFrame(raw_data)
df_data.head()

foreign

make

price

weight

1

Domestic

AMCPacer

4749

3350

2

Domestic

AMCSpirit

3799

2640

3

Domestic

BuickCentury

4816

3250

6

Domestic

BuickOpel

4453

2230

7

Domestic

BuickRegal

5189

3280

保存为不同类型:

data_path = os.path.join(os.getcwd(), 'data')
with open(os.path.join(data_path, 'text_sample.txt'), 'w+') as file:
    file.write('Learning Python is great. nGood luck!')
df_data.to_excel(os.path.join(data_path, 'excel_sample.xlsx'))
df_data.to_csv(os.path.join(data_path, 'csv_sample.csv'))
df_data.to_stata(os.path.join(data_path, 'stata_sample.dta'))
df_data.to_json(os.path.join(data_path, 'json_sample.json'))

注意: pandas 没有 .to_sas() 函数。