码迷,mamicode.com
首页 > 其他好文 > 详细

解读pandas的IO操作

时间:2019-01-11 22:08:01      阅读:645      评论:0      收藏:0      [点我收藏+]

标签:css   hup   csv文件   controls   facet   support   tooltip   sky   问题   

 

pandas文件读取和输出?

 

数据分析过程中经常需要进行读写操作,Pandas实现了很多 IO 操作的API,这里简单做了一个列举。?

格式类型数据描述ReaderWriter
text CSV read_ csv to_csv
text JSON read_json to_json
text HTML read_html to_html
text clipboard read_clipboard to_clipboard
binary Excel read_excel to_excel
binary HDF5 read_hdf to_hdf
binary Feather read_feather to_feather
binary Msgpack read_msgpack to_msgpack
binary Stata read_stata to_stata
binary SAS read_sas
binary Python Pickle read_pickle to_pickle
SQL SQL read_sql to_sql
SQLGoogle Big Query read_gbq to_gbq
 

主要内容?

文件读取

  • 1.read_csv
  • 2.read_excel

文件保存

  • 1.to_csv
  • 2.to_excel
  • 3.to_sql
 

文件读取?

In [43]:
from io import StringIO
import pandas as pd
 
    1. read_csv

      读取 csv 文件算是一种最常见的操作了。假如已经有人将一些用户的信息记录在了一个csv文件中,我们如何通过 Pandas 读取呢?
      读取之前先来看下这个文件里的内容吧。

In [44]:
data = pd.read_csv(‘../friends.csv‘,encoding=‘utf-8‘,index_col=‘NickName‘)
data.head()
Out[44]:
 
 Unnamed: 0SexProvinceCitySignature
NickName     
张亚飞 0 1 NaN NaN 我一定会证明我努力的意义,即使生活一次一次否定它。
Messi 1 1 山西 晋城 NaN
2 2 山西 晋城 NaN
Irving 3 1 Offaly NaN NaN
苊儿 4 2 山西 晋中 希望外表的放肆遮得住内心的柔弱
 

可以看到,读取出来生成了一个 DataFrame,索引是自动创建的一个数字,我们可以设置参数 index_col 来将某列设置为索引,可以传入索引号或者名称。

In [4]:
"""
除了可以从文件中读取,我们还可以从 StringIO 对象中读取。
"""
data="name,age,birth,sex\nTom,18.0,2000-02-10,\nBob,30.0,1988-10-17,male"
print(data)
df = pd.read_csv(StringIO(data))
df
 
name,age,birth,sex
Tom,18.0,2000-02-10,
Bob,30.0,1988-10-17,male
Out[4]:
 
 nameagebirthsex
0 Tom 18.0 2000-02-10 NaN
1 Bob 30.0 1988-10-17 male
 
  • 当然了,你还可以设置参数 sep 来自定义字段之间的分隔符,设置参数 lineterminator 来自定义每行的分隔符。
In [5]:
data = "name|age|birth|sex~Tom|18.0|2000-02-10|~Bob|30.0|1988-10-17|male"
df = pd.read_csv(StringIO(data), sep="|", lineterminator="~")
df
Out[5]:
 
 nameagebirthsex
0 Tom 18.0 2000-02-10 NaN
1 Bob 30.0 1988-10-17 male
 
  • 在读取时,解析器会进行类型推断,任何非数字列都会以对象dtype的形式出现。当然我们也可以自己指定数据类型
In [7]:
df = pd.read_csv(StringIO(data), sep="|", lineterminator="~", dtype={"age": int})
df
Out[7]:
 
 nameagebirthsex
0 Tom 18 2000-02-10 NaN
1 Bob 30 1988-10-17 male
 
  • Pandas 默认将第一行作为标题,但是有时候,csv文件并没有标题,我们可以设置参数 names 来添加标题。
In [9]:
data="Tom,18.0,2000-02-10,\nBob,30.0,1988-10-17,male"
print(data)
df = pd.read_csv(StringIO(data), names=["name", "age", "birth", "sex"])
df
 
Tom,18.0,2000-02-10,
Bob,30.0,1988-10-17,male
Out[9]:
 
 nameagebirthsex
0 Tom 18.0 2000-02-10 NaN
1 Bob 30.0 1988-10-17 male
 
  • 有时候可能只需要读取部分列的数据,可以指定参数 user_cols
In [10]:
data="name,age,birth,sex\nTom,18.0,2000-02-10,\nBob,30.0,1988-10-17,male"
print(data)
df = pd.read_csv(StringIO(data), usecols=["name", "age"])
df
 
name,age,birth,sex
Tom,18.0,2000-02-10,
Bob,30.0,1988-10-17,male
Out[10]:
 
 nameage
0 Tom 18.0
1 Bob 30.0
 
  • 关于缺失值的处理,也是有技巧的。默认参数 keep_default_na=False,会将空值都填充为 NaN。
In [14]:
print(pd.read_csv(StringIO(data)))
df = pd.read_csv(StringIO(data), keep_default_na=False)
df
 
  name   age       birth   sex
0  Tom  18.0  2000-02-10   NaN
1  Bob  30.0  1988-10-17  male
Out[14]:
 
 nameagebirthsex
0 Tom 18.0 2000-02-10  
1 Bob 30.0 1988-10-17 male
 
  • 有时候,空值的定义比较广泛,假定我们认为 18 也是空值,那么将它加入到参数 na_values 中即可。
In [16]:
df = pd.read_csv(StringIO(data), na_values=[18])
df
Out[16]:
 
 nameagebirthsex
0 Tom NaN 2000-02-10 NaN
1 Bob 30.0 1988-10-17 male
 
  • to_json

    通常在得到了 DataFrame 之后,有时候我们需要将它转为一个 json 字符串,可以使用 to_json 来完成。 转换时,可以通过指定参数 orient 来输出不同格式的格式,之后以下几个参数:

    • split 字典像索引 - > [索引],列 - > [列],数据 - > [值]}
    • records 列表像{[列 - >值},…,{列 - >值}]
    • index 字典像{索引 - > {列 - >值}}
    • columns 字典像{列 - > {索引 - >值}}
    • values 只是值数组

DataFrame 默认情况下使用 columns 这种形式,Series 默认情况下使用 index 这种形式。

  • 设置为 columns 后会将数据作为嵌套JSON对象进行序列化,并将列标签作为主索引。
  • 设置为index 后会将数据作为嵌套JSON对象进行序列化,并将索引标签作为主索引。
  • 设置为 records 后会将数据序列化为列 - >值记录的JSON数组,不包括索引标签。
  • 设置为 values 后会将是一个仅用于嵌套JSON数组值,不包含列和索引标签。
  • 设置为 split 后会将序列化为包含值,索引和列的单独条目的JSON对象。
In [21]:
df = pd.read_csv("../friends.csv", index_col="NickName").head()
print(df)
df.to_json()
 
          Unnamed: 0  Sex Province City                  Signature
NickName                                                          
张亚飞                0    1      NaN  NaN  我一定会证明我努力的意义,即使生活一次一次否定它。
Messi              1    1       山西   晋城                        NaN
夕                  2    2       山西   晋城                        NaN
Irving             3    1   Offaly  NaN                        NaN
苊儿                 4    2       山西   晋中            希望外表的放肆遮得住内心的柔弱
Out[21]:
‘{"Unnamed: 0":{"\\u5f20\\u4e9a\\u98de":0,"Messi":1,"\\u5915":2,"Irving":3,"\\u82ca\\u513f":4},"Sex":{"\\u5f20\\u4e9a\\u98de":1,"Messi":1,"\\u5915":2,"Irving":1,"\\u82ca\\u513f":2},"Province":{"\\u5f20\\u4e9a\\u98de":null,"Messi":"\\u5c71\\u897f","\\u5915":"\\u5c71\\u897f","Irving":"Offaly","\\u82ca\\u513f":"\\u5c71\\u897f"},"City":{"\\u5f20\\u4e9a\\u98de":null,"Messi":"\\u664b\\u57ce","\\u5915":"\\u664b\\u57ce","Irving":null,"\\u82ca\\u513f":"\\u664b\\u4e2d"},"Signature":{"\\u5f20\\u4e9a\\u98de":"\\u6211\\u4e00\\u5b9a\\u4f1a\\u8bc1\\u660e\\u6211\\u52aa\\u529b\\u7684\\u610f\\u4e49\\uff0c\\u5373\\u4f7f\\u751f\\u6d3b\\u4e00\\u6b21\\u4e00\\u6b21\\u5426\\u5b9a\\u5b83\\u3002","Messi":null,"\\u5915":null,"Irving":null,"\\u82ca\\u513f":"\\u5e0c\\u671b\\u5916\\u8868\\u7684\\u653e\\u8086\\u906e\\u5f97\\u4f4f\\u5185\\u5fc3\\u7684\\u67d4\\u5f31"}}‘
In [22]:
print(df.to_json(orient="index"))
 
{"\u5f20\u4e9a\u98de":{"Unnamed: 0":0,"Sex":1,"Province":null,"City":null,"Signature":"\u6211\u4e00\u5b9a\u4f1a\u8bc1\u660e\u6211\u52aa\u529b\u7684\u610f\u4e49\uff0c\u5373\u4f7f\u751f\u6d3b\u4e00\u6b21\u4e00\u6b21\u5426\u5b9a\u5b83\u3002"},"Messi":{"Unnamed: 0":1,"Sex":1,"Province":"\u5c71\u897f","City":"\u664b\u57ce","Signature":null},"\u5915":{"Unnamed: 0":2,"Sex":2,"Province":"\u5c71\u897f","City":"\u664b\u57ce","Signature":null},"Irving":{"Unnamed: 0":3,"Sex":1,"Province":"Offaly","City":null,"Signature":null},"\u82ca\u513f":{"Unnamed: 0":4,"Sex":2,"Province":"\u5c71\u897f","City":"\u664b\u4e2d","Signature":"\u5e0c\u671b\u5916\u8868\u7684\u653e\u8086\u906e\u5f97\u4f4f\u5185\u5fc3\u7684\u67d4\u5f31"}}
In [23]:
print(df.to_json(orient="records"))
 
[{"Unnamed: 0":0,"Sex":1,"Province":null,"City":null,"Signature":"\u6211\u4e00\u5b9a\u4f1a\u8bc1\u660e\u6211\u52aa\u529b\u7684\u610f\u4e49\uff0c\u5373\u4f7f\u751f\u6d3b\u4e00\u6b21\u4e00\u6b21\u5426\u5b9a\u5b83\u3002"},{"Unnamed: 0":1,"Sex":1,"Province":"\u5c71\u897f","City":"\u664b\u57ce","Signature":null},{"Unnamed: 0":2,"Sex":2,"Province":"\u5c71\u897f","City":"\u664b\u57ce","Signature":null},{"Unnamed: 0":3,"Sex":1,"Province":"Offaly","City":null,"Signature":null},{"Unnamed: 0":4,"Sex":2,"Province":"\u5c71\u897f","City":"\u664b\u4e2d","Signature":"\u5e0c\u671b\u5916\u8868\u7684\u653e\u8086\u906e\u5f97\u4f4f\u5185\u5fc3\u7684\u67d4\u5f31"}]
In [24]:
print(df.to_json(orient="values"))
 
[[0,1,null,null,"\u6211\u4e00\u5b9a\u4f1a\u8bc1\u660e\u6211\u52aa\u529b\u7684\u610f\u4e49\uff0c\u5373\u4f7f\u751f\u6d3b\u4e00\u6b21\u4e00\u6b21\u5426\u5b9a\u5b83\u3002"],[1,1,"\u5c71\u897f","\u664b\u57ce",null],[2,2,"\u5c71\u897f","\u664b\u57ce",null],[3,1,"Offaly",null,null],[4,2,"\u5c71\u897f","\u664b\u4e2d","\u5e0c\u671b\u5916\u8868\u7684\u653e\u8086\u906e\u5f97\u4f4f\u5185\u5fc3\u7684\u67d4\u5f31"]]
In [25]:
print(df.to_json(orient="split"))
 
{"columns":["Unnamed: 0","Sex","Province","City","Signature"],"index":["\u5f20\u4e9a\u98de","Messi","\u5915","Irving","\u82ca\u513f"],"data":[[0,1,null,null,"\u6211\u4e00\u5b9a\u4f1a\u8bc1\u660e\u6211\u52aa\u529b\u7684\u610f\u4e49\uff0c\u5373\u4f7f\u751f\u6d3b\u4e00\u6b21\u4e00\u6b21\u5426\u5b9a\u5b83\u3002"],[1,1,"\u5c71\u897f","\u664b\u57ce",null],[2,2,"\u5c71\u897f","\u664b\u57ce",null],[3,1,"Offaly",null,null],[4,2,"\u5c71\u897f","\u664b\u4e2d","\u5e0c\u671b\u5916\u8868\u7684\u653e\u8086\u906e\u5f97\u4f4f\u5185\u5fc3\u7684\u67d4\u5f31"]]}
 
    1. read_excel():具体参数read_eccel与read_csv相似
In [46]:
df = pd.read_excel(‘data/adverse_reaction_database.xlsx‘)
df.head()
Out[46]:
 
 药品通用名称适应症不良反应
0 盐酸甲氧氯普胺注射液 肿瘤放化疗等所致恶心、呕吐 急性尿潴留,不能自行小便。
1 甲苯丙胺丸 NaN 紧张恐惧。
2 复方磺胺甲噁唑片 支气管炎及肺部、尿路及肠道感染等 恶心、食欲不振,胃部烧灼感。
3 利福平片 抗结核 渐发现全身皮肤多处紫红色斑点及持续明道流血。
4 依那普利 慢性心衰和(或)顽固性心衰 气促、心悸,下肢水肿。
 

文件保存:这里主要介绍三种常用的保存方法?

  • to_excel
  • to_csv
  • to_sql
 

数据我就按比较常见的列表嵌套字典来演示了,这种数据结构也是在各个场景下经常用到的数据结构[{},{},{}…]

In [29]:
import pandas as pd
data = [
       {"name":"张三","age":18,"city":"北京"},
       {"name":"李四","age":19,"city":"上海"},
       {"name":"王五","age":20,"city":"广州"},
       {"name":"赵六","age":21,"city":"深圳"},
       {"name":"孙七","age":22,"city":"武汉"}
]
df = pd.DataFrame(data,columns=["name","age","city"])
df
Out[29]:
 
 nameagecity
0 张三 18 北京
1 李四 19 上海
2 王五 20 广州
3 赵六 21 深圳
4 孙七 22 武汉
In [32]:
df.to_csv("data/csv_file.csv",encoding="utf-8",index=False)
df
Out[32]:
 
 nameagecity
0 张三 18 北京
1 李四 19 上海
2 王五 20 广州
3 赵六 21 深圳
4 孙七 22 武汉
 

注意事项:

  • 1、一般情况下我们用utf-8编码进行保存,如果出现中文编码错误,则可以依次换用gbk,gb2312 , gb18030,一般总能成功的,本例中用utf-8
  • 2、to_csv方法,具体参数还有很多,可以去看官方文档,这里提到一个index = False参数,表示保存csv的时候,我们不保存pandas 的Data frame的行索引1234这样的序号,默认情况不加的话是index = True,会有行号(如下图),这点在保存数据库mysql的时候体现尤其明显,不注意的话可能会出错
In [31]:
df.to_csv("data/csv_file.csv",encoding="utf-8")
df
Out[31]:
 
 nameagecity
0 张三 18 北京
1 李四 19 上海
2 王五 20 广州
3 赵六 21 深圳
4 孙七 22 武汉
 
  • 输出excel文件
In [42]:
writer = pd.ExcelWriter(‘data/excel.xlsx‘)
df.to_excel(writer, sheet_name=‘user‘, index=False)
writer.save()
 

技术分享图片技术分享图片

 
  • 保存mysql
In [40]:
from sqlalchemy import create_engine

table_name = "user"

engine = create_engine(
    "mysql+pymysql://root:0000@127.0.0.1:3306/db_test?charset=utf8",
    max_overflow=0,  # 超过连接池大小外最多创建的连接
    pool_size=5,  # 连接池大小
    pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
    pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
conn = engine.connect()
df.to_sql(table_name, conn, if_exists=‘append‘,index=False)
           技术分享图片
 

技术分享图片

 
  • 上面代码已经实现将我们构造的df数据保存MySQL,现在提一些注意点

注意事项:
1、我们用的库是sqlalchemy,官方文档提到to_sql是被sqlalchemy支持
文档地址:
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_sql.html
2、数据库配置用你自己的数据库配置,db_flag为数据库类型,根据不同情况更改,在保存数据之前,要先创建数据库字段,下图是我这边简单创建的字段

技术分享图片

技术分享图片 3、engine_config为数据库连接配置信息
4、create_engine是根据数据库配置信息创建连接对象
5、if_exists = ‘append‘,追加数据
6、index = False 保存时候,不保存df的行索引,这样刚好df的3个列和数据库的3个字段一一对应,正常保存,如果不设置为false的话,数据相当于4列,跟MySQL 3列对不上号,会报错

  • 这里提个小问题,比如我们想在遍历的时候来一条数据,保存一条,而不是整体生成Dataframe后才保存,该怎么做?上面提到if_exists,可以追加,用这个即可实现,包括保存csv同样也有此参数,可以参考官方文档

 

解读pandas的IO操作

标签:css   hup   csv文件   controls   facet   support   tooltip   sky   问题   

原文地址:https://www.cnblogs.com/zhangyafei/p/10257379.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!