数据分析过程中经常需要进行读写操作。
Pandas实现了很多 IO 操作的API,文件格式以及读写的方法,这里简单做了一个列举。
格式类型 | 数据描述 | Reader | Writer |
---|---|---|---|
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 |
SQL | Google Big Query | read_gbq | to_gbq |
可以看到,Pandas 的 I/O API是像
pd.read_csv() 一样访问的一组顶级 reader 函数,
相应的 writer 函数是像 df.to_csv() 那样访问的对象方法。
# 导入相关库
import numpy as np
import pandas as pd
from io import StringIO
读取文件
read_csv
读取 csv 文件算是一种最常见的操作了。假如已经有人将一些用户的信息记录在了一个csv文件中,我们如何通过 Pandas 读取呢?
新建txt文件
在问文件中写:
name,age,birth,sex
Tom,18.0,2000-02-10,
Bob,30.0,1988-10-17,male
数据用逗号隔开即可。
2.将文件复制到与py文件同级目录(也可以不复制,为了方便)
![](https://img.haomeiwen.com/i22697958/f6bd5b0bff68ad8d.png)
3.在该py文件中读取文件
# 导入相关库
import numpy as np
import pandas as pd
from io import StringIO
file = pd.read_csv("user_info.csv")
print(file)
print(type(file)) # # <class 'pandas.core.frame.DataFrame'>
# name age birth sex
# 0 Tom 18.0 2000-02-10 NaN
# 1 Bob 30.0 1988-10-17 male
可以看到,读取出来生成了一个 DataFrame,索引是自动创建的一个数字,我们可以设置参数 index_col 来将某列设置为索引,可以传入索引号或者名称。
file = pd.read_csv('user_info.csv',index_col='name')
print(file)
# age birth sex
# name
# Tom 18.0 2000-02-10 NaN
# Bob 30.0 1988-10-17 male
从 StringIO 对象中读取
1.index_col='列名'
将字符串转为字节,然后用read_csv进行读取
data="name,age,birth,sex\nTom,18.0,2000-02-10,\nBob,30.0,1988-10-17,male"
print(data) # String
# name,age,birth,sex
# Tom,18.0,2000-02-10,
# Bob,30.0,1988-10-17,male
# 转为字节
sio = StringIO(data)
print(sio)
# <_io.StringIO object at 0x00000148FD3A4318>
# 读取
df = pd.read_csv(sio,index_col='name')
print(df)
# age birth sex
# name
# Tom 18.0 2000-02-10 NaN
# Bob 30.0 1988-10-17 male
2.sep="符号", lineterminator="符号"
字符串还可以是这种形式:
sep 来自定义字段之间的分隔符,设置参数 lineterminator 来自定义每行的分隔符。
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="~",index_col='name')
print(df)
# age birth sex
# name
# Tom 18.0 2000-02-10 NaN
# Bob 30.0 1988-10-17 male
3.dytype={''列名:类型名}
在读取时,解析器会进行类型推断,任何非数字列都会以object的dtype的形式出现。当然我们也可以自己指定数据类型。
df = pd.read_csv(StringIO(data), sep="|", lineterminator="~", dtype={"age": int})
print(df)
# name age birth sex
# 0 Tom 18 2000-02-10 NaN
# 1 Bob 30 1988-10-17 male
4.names=['列名','列名',...]
Pandas 默认将第一行作为标题,但是有时候,csv文件并没有标题,我们可以设置参数 names来添加标题。
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"])
print(df)
# name age birth sex
# 0 Tom 18.0 2000-02-10 NaN
# 1 Bob 30.0 1988-10-17 male
5.usecols=['列名','列名',...]
有时候可能只需要读取部分列的数据,可以指定参数 user_cols
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"])
print(df)
# name age
# 0 Tom 18.0
# 1 Bob 30.0
6.缺失值处理
关于缺失值的处理,也是有技巧的。默认参数 keep_default_na=False,会将空值都填充为 NaN。
df = pd.read_csv(StringIO(data))
df = pd.read_csv(StringIO(data), keep_default_na=False)
print(df)
# name age birth sex
# 0 Tom 18.0 2000-02-10 NaN
# 1 Bob 30.0 1988-10-17 male
na_values=[]
有时候,空值的定义比较广泛,假定我们认为 18 也是空值,那么将它加入到参数 na_values中即可,那么18也会变为NaN。
df= pd.read_csv(StringIO(data), na_values=[18])
print(df)
# name age birth sex
# 0 Tom NaN 2000-02-10 NaN
# 1 Bob 30.0 1988-10-17 male
了解了 pd.read_csv 如何使用之后,to_csv 就非常方便了,这里就不做介绍了。
to_json
通常在得到了 DataFrame 之后,有时候我们需要将它转为一个 json 字符串,可以使用 to_json 来完成。
转换时,可以通过指定参数 orient 来输出不同格式的格式,之后以下几个参数:
参数值 | 格式 |
---|---|
split | 字典像索引 - > [索引],列 - > [列],数据 - > [值]} |
records | 列表像{[列 - >值},…,{列 - >值}] |
index | 字典像{索引 - > {列 - >值}} |
columns | 字典像{列 - > {索引 - >值}} |
values | 只是值数组 |
DataFrame 默认情况下使用 columns 这种形式,Series 默认情况下使用 index 这种形式。
设置为 columns 后会将数据作为嵌套JSON对象进行序列化,并将列标签作为主索引。
print(df)
# age birth sex
# name
# Tom 18.0 2000-02-10 NaN
# Bob 30.0 1988-10-17 male
json = df.to_json()
print(json)
# {"age":{"Tom":18.0,"Bob":30.0},"birth":{"Tom":"2000-02-10","Bob":"1988-10-17"},"sex":{"Tom":null,"Bob":"male"}}
json = df.to_json(orient='index')
print(json)
# {"Tom":{"age":18.0,"birth":"2000-02-10","sex":null},"Bob":{"age":30.0,"birth":"1988-10-17","sex":"male"}}
print(df.to_json(orient="records"))
# [{"age":18.0,"birth":"2000-02-10","sex":null},{"age":30.0,"birth":"1988-10-17","sex":"male"}]
print(df.to_json(orient="values"))
# [[18.0,"2000-02-10",null],[30.0,"1988-10-17","male"]]
print(df.to_json(orient="split"))
# {"columns":["age","birth","sex"],"index":["Tom","Bob"],"data":[[18.0,"2000-02-10",null],[30.0,"1988-10-17","male"]]}
对于 read_json,这些参数也是同样的道理。
网友评论