作者:杨士锦 周岩 书生
编者按
当我们开始着手做一个数据分析项目时,选择和导入数据集是第一个步骤,而导出数据虽然非必需,但有时候我们也需要保存处理或者分析后的结果,方便下次使用。在pandas中,它已经为我们提供了很多不同格式数据的导入和导出方法,下面这篇文章将具体介绍一些较为常用的方法,包括excel、csv文件以及数据库的导入导出等。
数据导入和导出是pandas中很基础且重要的一个部分。pandas提供了很多不同格式数据的导入和导出方法,可以将其他格式数据转为DataFrame格式。我们可以将list、dict格式数据转为DataFrame格式,也可以从本地的csv、json等文本格式数据和sql、MongoDB等数据库中读取和保存数据等等。下面就分别以三大类介绍一些常见的数据格式的导入与导出。
下文中所有的示例代码都是在jupyter notebook中创作,还不太了解jupyter的小伙伴,可以先看看这篇文章哦:数据科学 | 始于Jupyter Notebooks:一份全面的初学者使用指南。
1.1 list
一般读取一个list,生成的结果如下:
运行结果:
如果读取的list中的每个元素都是一个元组,会发生什么呢?
运行结果:
如果忽略columns的话,第二个list的值不是列名,而是默认生成索引名,如下:
运行结果:
1.2 dict
这里我们以一个字典为数据,看下不同操作的结果有何不同。
直接调用DataFrame进行读取的话,生成的DataFrame结构如下:
运行结果:
需要说明的是:from_dict这个方法只有在pandas 0.23版本后才有,如果在早期的版本如0.19中调用会出现报错。
如果我们想以a,b作为索引,以list中的每个值分别为一列怎么操作呢?
运行结果:
如果进一步想让a、b生成列的话,调用reset_index方法即可。
运行结果:
但是如果我们想把字典的key和value分别生成两列,如何操作呢?
一种方法是:
还有一种方法依然是利用from_dict,不过就需要将value中的list提前转化成字符串,然后再进行操作即可。
1.3 np.array
numpy是比pandas更底层一些的数据操作工具,pandas的很多操作也是基于numpy进行的,比如numpy就支持直接读取txt文件。比如有这样一个txt文件:
一共有4行8列的数据,数据间用空格隔开,表头带有%,那么读取的时候可以用loadtxt函数进行导入:
运行结果:
可以看到数据自动剔除了表头,并且只用了其中指定的列。接下来就可以将array导入到pandas中:
我们就可以得到类似用list构建DataFrame的效果了:
1.4 其他方式
当然需要导入文本并不规则的时候,可以考虑直接利用python中的文件读取来一行一行的读取文件,然后利用json或者re等字符串处理包来处理数据,最后整合成DataFrame:
当然这个方法要结合具体的数据来看,这里就不展开介绍了。
2.1 CSV文件
2.1.1 导入csv数据
常用参数解析:
● filepath_or buffer: str, path object or file-like object。指定传入的文件路径,必须传入的参数。
● sep: str。指定分隔符,默认是逗号分隔符。
● header: int, list or int。指定行数用来作为列名。默认是如果没有传入names参数,则header=0,用第一行作为列名,否则header=None,以传入的names作为列名。另外如果传入的是list,例如[0,1,3],则是以第1、2、4这些行作为多级列名,且中间的行,第3行会被忽略,数据从第5行开始。
● names: array-like, optional。指定文件的列名。如果文件中没有标题行,建议传入此参数。
● index_col: int, str, or sequence of int / str, or False。指定文件的索引,默认为None。
ex1.csv内容如下:
导入ex1.csv
运行结果:
ex2.csv文件没有标题行
设置sep和header参数,导入ex2.csv
运行结果:
设置sep和names参数,此时header默认为None
运行结果:
对ex1.csv设置多级标题,将第1、2、4行作为标题,数据从第5行开始
运行结果:
导入ex1.csv,指定索引为message一列
运行结果:
导入ex1.csv,指定第1和2列作为多重索引
运行结果:
2.1.2 导出csv数据
参用参数解析:
● path_or_buf: str or file handle。指定保存文件路径,必须传入的参数,默认为None。
● index: bool。导出的csv是否包含索引,默认为True。
● header: bool or list of str。导出的csv是否包含标题行,默认为True。
● sep: str。指定导出的csv文件的分隔符,默认为逗号分隔符。
● encoding: str。指定导出的csv文件的编码,默认为utf-8
2.2 excel文件
2.2.1 导入excel文件
常用参数解析:
read_excel和read_csv的用法差不多,一个需要注意的参数是sheet_name。这个参数是指定读取该excel中具体哪个表的数据,默认为0,即为第一个表。如果传入1,则为第2个表;可指定传入表名,如"Sheet1";也可传入多个表,如[0,'Sheet3'],传入第一个表和名为'Sheet3'的表。
读取ex1.xlsx文件,默认为读取第一个表
运行结果:
读取ex1.xlsx文件的第2个表
运行结果:
读取ex1.xlsx文件的第2个表和名为"Sheet3"的表,返回的是对象是OrderedDict。OrderedDict是dict的子类,与dict不同的是,它记住了内容的顺序。
运行结果:
在这个orderedDict中,有两个key。第一个key是1,对应的value为该表的内容;第二个key是'Sheet3',对应的value是Sheet3表格的内容。我们选取key,就能得到相应的value。
运行结果:
运行结果:
2.2.2 导出excel文件
常用参数解析:
● excel_writer: str。指定保存文件路径。
● sheet_name: str。指定excel文件的表名,默认为’Sheet1‘。
● index:bool。是否保存索引,默认为True。
2.3 txt文件
2.3.1 导入txt文件
常用参数解析:
read_table与read_csv的唯一区别是,read_csv默认的sep参数是逗号分隔符,而read_table默认是't',制表符。所以这两个方法是通用的,只要设置好分隔符,都可以读取csv和txt文件。
ex3.txt文件的内容如下:
导入ex3.txt文件
运行结果:
将sep参数设置为逗号,同样能读取ex1.csv文件
运行结果:
2.3.2 导出txt文件
使用to_csv的方法
2.4 csv和xlsx的选择
当我们可以选择保存为csv或者xlsx格式,方便下次可以使用的时候,是选择保存为csv还是excel呢?除了考虑csv和excel文件大小之外(相同的数据下excel文件比csv文件小),这里可以考虑下read_csv和read_xlsx的性能问题。在stackoverflow上有人对这两种导入方法进行了一个简单的测试。
测试文件:同样的数据集(分别是320MB的csv文件和16MB的xlsx文件)
电脑硬件:i7-7700k,SSD
python环境:Anaconda Python 3.5.3, pandas 0.19.2
2.5 json
2.5.1 导入json文件
常用参数解析:
● path_or_buf: 指定文件路径,默认为None,必须传入的参数。
●orient: json字符串格式,默认为None。这里有split,records,index,columns,values五种选择可选。
● typ: 要转换为series还是dataframe,默认为frame。当typ=frame时,orient可选split/records/index,默认为columns;当typ=series,orient可选split/records/index/columns/value,orient默认为index。
split格式:dict like {index -> [index], columns -> [columns], data -> [values]}, 例如下面的ex4.json文件。
导入ex4.json
运行结果:
records格式:list like [{column -> value}, ..., {column -> value}],例如下面的ex5.json文件。
导入ex5.json
导入ex5.json
运行结果同上。
如果是转为series格式:
运行结果:
index格式: dict like {index -> {column -> vlaue}},例如下面的ex6.json文件。
导入ex6.json
运行结果:
如果是转为series格式:
运行结果:
columns格式:dict like {column -> {index -> value}},例如下面的ex7.json文件。当typ='frame'时,orient默认为这个格式。
导入ex7.json
运行结果:
用columns格式读取ex6.json,其实与index格式的结果是行列的转置。
运行结果:
values格式:just the values array,例如下面的ex8.json文件。
导入ex8.json
运行结果:
2.5.2 导出json文件
常用参数解析:
● orient: string。指定导出json的格式。DataFrame默认是columns,Series默认是index
dataframe导出json,命名为out_ex4.json
series导出json,命名为out_ex5.json
3.1 MySQL
在开始之前,请确保环境中的python为3.x版本,且已经安装并开启mysql服务。这里我们使用pymysql库来连接mysql。首先需要通过pip安装pymysql。安装后,可以通过import语句检验是否已经安装成功。如果没有报错,则说明安装成功。
3.1.1 数据导入mysql
3.1.2 读取mysql数据
通过sql语句查询数据
运行结果:
将结果转换为Dataframe格式
运行结果:
关闭数据库连接:
3.2 PostgreSQL
psycopg2是Python语言的PostgreSQL数据库接口之一,这里我们使用psycopg2连接,首先同样请确保环境中已经安装postgreSQL,以及已通过pip安装psycopg2了。
3.2.1 读取postgreSQL的数据
返回的data结果是一个以各行数据为元组的列表,如下:
可以通过pandas对data进行进一步处理:pd.DataFrame(data)。
在insert的时候,需要注意以下几点:
1.表中的字段不需要加引号;
2.插入的每行数值用括号包围,其中各个字段以逗号间隔,字符串型必须加引号;
3.以上sql命令可见,一条sql命令可以插入多条数据,只需要连接各个数据,最终commit一次就好;
4.另外在写入PG的时候,应该注意PG中的数据如果出现单引号“ ' ”会出现错误,所以必须先使用replace替换成其他的内容方可写入。
3.2.2 数据写入postgreSQL
3.3 支持多种数据库 — SQLAlchemy
SQLAlchemy是python下的一款数据库对象关系映射工具(ORM工具),能满足大多数数据库操作需求,且支持多种数据库引擎,能连接上文提及的MySQL, PostgreSQL, Oracle之外,还支持Mircosoft SQL Server, SQLite等的数据库。另外在pandas中,配合使用SQLalchemy连接数据库,可以实现更简便高效的查询和导入数据的操作,因为pandas已经帮你写好一些常用的方法了。
下面我们以连接mysql数据库为例子介绍用法,首先还是需要先通过pip安装sqlalchemy和pymysql。
3.3.1 读取数据库数据
在pandas中,我们可以通过read_sql_table和read_sql的方法来读取数据库,pandas会帮我们将结果直接转为Dataframe的格式,这对于需要Dataframe格式数据的来说是非常方便的。
读取数据下现有所有的表
运行结果:
读取数据库下某个表的数据
运行结果:
根据sql语句查询数据:
运行结果:
3.3.2 数据导入数据库
将Dataframe格式的数据导入到数据库中,我们可以使用to_sql的方法。
● name:导入库的表的名字
● if_exists:默认为"fail",表示如果表不存在,直接报错;可选"replace",导入的Dataframe直接覆盖该表;可选"append",将数据添加到表的后面。
3.4 MongoDB
MongoDB 是目前最流行的 NoSQL 数据库之一,使用的数据类型 BSON(类似 JSON)。这里我们使用PyMongo连接MongoDB数据库。
3.4.1 将数据导入数据库
3.4.2 读取数据库数据
运行结果:
运行结果:
运行结果:
参考文献:
1.《Python for Data Analysis》
2.pandas官方文档:
https://pandas.pydata.org/pandas-docs/stable/index.html
3.https://stackoverflow.com/questions/31362573/performance-difference-in-pandas-read-table-vs-read-csv-vs-from-csv-vs-read-e
4.https://www.runoob.com/python3/python3-mysql.html
5.https://www.runoob.com/python3/python-mongodb.html