Skip to content

数据读取与存储

我们的数据大部分存在于文件当中,所以 pandas 会支持复杂的 IO 操作,pandas 的 API 支持众多的文件格式,如 CSV、SQL、XLS、JSON、HDF5。

注:最常用的 HDF5 和 CSV 文件

官方文档:https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#csv-text-files

提示

文件下载 stock_day.csv

CSV

read_csv

pandas.read_csv(filepath_or_buffer, sep =',', usecols)

  • filepath_or_buffer: 文件路径
  • sep : 分隔符,默认用","隔开
  • usecols: 指定读取的列名,列表形式
  • encoding: 编码

举例:读取之前的股票的数据

python
import pandas as pd

pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)
"""
usecols 指定需要提取的列
"""
df = pd.read_csv(
    'stock_day.csv',
    sep=',',  # 分隔符,默认为逗号
    # usecols=['open', 'high', 'close', 'low'],  # 指定获取的列
    encoding='utf-8',
    index_col=False,  # 是否读取索引
    names=['开盘价', '最高价', '收盘价', '最低价'],  # 直接指定列明
    engine='python'  # c 速度更快, python 功能更完整
)
print(df)

df.to_csv('stock_day_back.csv')

to_csv

DataFrame.to_csv(path_or_buf=None, sep=', ’, columns=None, header=True, index=True, mode='w', encoding=None)

  • path_or_buf :文件路径
  • sep :分隔符,默认用","隔开
  • columns :选择需要的列索引
  • header :boolean or list of string, default True, 是否写进列索引值
  • index:是否写进行索引
  • mode: 'w':重写, 'a' 追加

举例:保存读取出来的股票数据

  • 保存 'open' 列的数据,然后读取查看结果
python
# 选取 10 行数据保存,便于观察数据
df[:10].to_csv(
    'stock_day_day10.csv',
    index=False,  # 是否保留索引
    columns=['open']  # 保存列
)

会发现将索引存入到文件当中,变成单独的一列数据。如果需要删除,可以指定 index 参数,删除原来的文件,重新保存一次。

python
# 读取,查看结果
pd.read_csv("stock_day_day10.csv")

open
23.53
22.8
22.88
22.25
21.49
21.4
20.7
21.2
21.79
22.69

JSON

JSON 是我们常用的一种数据交换格式,前面在前后端的交互经常用到,也会在存储的时候选择这种格式。所以我们需要知道 Pandas 如何进行读取和存储 JSON 格式。

read_json

pandas.read_json(path_or_buf=None, orient=None, typ='frame', lines=False)

  • 将 JSON 格式准换成默认的 Pandas DataFrame 格式

  • orient : string,Indication of expected JSON string format.

    • 'split' : dict like {index -> [index], columns -> [columns], data -> [values]}

      split 将索引总结到索引,列名到列名,数据到数据。将三部分都分开了

    • 'records' : list like [{column -> value}, ... , {column -> value}]

      records 以columns:values的形式输出

    • 'index' : dict like {index -> {column -> value}}

      index 以index:{columns:values}...的形式输出

    • 'columns' : dict like {column -> {index -> value}}

      ,默认该格式

      columns 以 columns:{index:values} 的形式输出

    • values : just the values array

      values 直接输出值

  • lines : boolean, default False

    按照每行读取 json 对象

  • typ : default ‘frame’, 指定转换成的对象类型 series 或者 dataframe

read_json 案例

这里使用一个简单的数据集,格式为 json,存储格式为:

json
[
  {
    "name": "邵帆",
    "job": "机修工",
    "address": "广西壮族自治区建国市花溪合肥街 t 座 303979"
  },
  {
    "name": "何丹丹",
    "job": "系统测试",
    "address": "湖北省沈阳市清城杨路 b 座 435741"
  },
  {
    "name": "范佳",
    "job": "汽车修理工",
    "address": "四川省建县丰都李街 e 座 707065"
  },
  {
    "name": "王云",
    "job": "服装/纺织/皮革工艺师",
    "address": "内蒙古自治区长沙市双滦巢湖路 D 座 438460"
  },
  {
    "name": "赵玉珍",
    "job": "ERP 技术开发",
    "address": "吉林省玉华市崇文杨路 l 座 846818"
  },
  {
    "name": "倪阳",
    "job": "销售行政专员",
    "address": "甘肃省欢县怀柔重庆路 H 座 950331"
  },
  {
    "name": "成莉",
    "job": "麻醉医生",
    "address": "广西壮族自治区文市华龙余路 q 座 603504"
  },
  {
    "name": "任斌",
    "job": "其他",
    "address": "湖北省上海县东城长沙街 D 座 331924"
  },
  {
    "name": "赵霞",
    "job": "医疗器械注册",
    "address": "北京市燕市双滦澳门路 I 座 647751"
  },
  {
    "name": "黄莹",
    "job": "其他",
    "address": "福建省惠州县涪城王街 j 座 216044"
  }
]

读取

orient 指定存储的 json 格式,lines 指定按照行去变成一个样本

python
import pandas as pd

df = pd.read_json(
    'info-records.json',
    orient='records'  # json 数据为字典
)
print(df)

结果为:

   name          job                   address
0   邵帆          机修工  广西壮族自治区建国市花溪合肥街 t 座 303979
1  何丹丹         系统测试       湖北省沈阳市清城杨路 b 座 435741
2   范佳        汽车修理工        四川省建县丰都李街 e 座 707065
3   王云  服装/纺织/皮革工艺师   内蒙古自治区长沙市双滦巢湖路 D 座 438460
4  赵玉珍      ERP 技术开发       吉林省玉华市崇文杨路 l 座 846818
5   倪阳       销售行政专员       甘肃省欢县怀柔重庆路 H 座 950331
6   成莉         麻醉医生    广西壮族自治区文市华龙余路 q 座 603504
7   任斌           其他      湖北省上海县东城长沙街 D 座 331924
8   赵霞       医疗器械注册       北京市燕市双滦澳门路 I 座 647751
9   黄莹           其他       福建省惠州县涪城王街 j 座 216044

to_json

DataFrame.to_json(path_or_buf=None, orient=None,lines=False)

  • 将 Pandas 对象存储为 json 格式
  • path_or_buf=None:文件地址
  • orient:存储的 json 形式,{‘split’,’records’,’index’,’columns’,’values’}
  • lines:一个对象存储为一行

存储文件

  • split 模式

    python
    df.to_json(
        'info-split.json',
        orient='split',
        # force_ascii=False,  # 是否编译为 ascii 编码
        date_format='utf-8'
    )

    结果

    json
    {
    "columns":["name","job","address"],
    "index":[0,1,2,3,4,5,6,7,8,9],
    "data":[["邵帆","机修工","广西壮族自治区建国市花溪合肥街 t 座 303979"],["何丹丹","系统测试","湖北省沈阳市清城杨路 b 座 435741"],["范佳","汽车修理工","四川省建县丰都李街 e 座 707065"],["王云","服装\/纺织\/皮革工艺师","内蒙古自治区长沙市双滦巢湖路 D 座 438460"],["赵玉珍","ERP 技术开发","吉林省玉华市崇文杨路 l 座 846818"],["倪阳","销售行政专员","甘肃省欢县怀柔重庆路 H 座 950331"],["成莉","麻醉医生","广西壮族自治区文市华龙余路 q 座 603504"],["任斌","其他","湖北省上海县东城长沙街 D 座 331924"],["赵霞","医疗器械注册","北京市燕市双滦澳门路 I 座 647751"],["黄莹","其他","福建省惠州县涪城王街 j 座 216044"]]
    }
  • index 模式

    python
    df.to_json(
        'info-index.json',
        orient='index',
        force_ascii=False,  # 是否编译为 ascii 编码
    )

    结果

    json
    {
    "0":{"name":"邵帆","job":"机修工","address":"广西壮族自治区建国市花溪合肥街 t 座 303979"},
    "1":{"name":"何丹丹","job":"系统测试","address":"湖北省沈阳市清城杨路 b 座 435741"},
    "2":{"name":"范佳","job":"汽车修理工","address":"四川省建县丰都李街 e 座 707065"},
    "3":{"name":"王云","job":"服装\/纺织\/皮革工艺师","address":"内蒙古自治区长沙市双滦巢湖路 D 座 438460"},
    "4":{"name":"赵玉珍","job":"ERP 技术开发","address":"吉林省玉华市崇文杨路 l 座 846818"},
    "5":{"name":"倪阳","job":"销售行政专员","address":"甘肃省欢县怀柔重庆路 H 座 950331"},
    "6":{"name":"成莉","job":"麻醉医生","address":"广西壮族自治区文市华龙余路 q 座 603504"},
    "7":{"name":"任斌","job":"其他","address":"湖北省上海县东城长沙街 D 座 331924"},
    "8":{"name":"赵霞","job":"医疗器械注册","address":"北京市燕市双滦澳门路 I 座 647751"},
    "9":{"name":"黄莹","job":"其他","address":"福建省惠州县涪城王街 j 座 216044"}
    }
  • table 模式

    python
    df.to_json(
        'info-table.json',
        orient='table',
        force_ascii=False
    )

    结果

    json
    {"schema":{
      "fields":[
        {"name":"index","type":"integer"},
        {"name":"name","type":"string"},
        {"name":"job","type":"string"},
        {"name":"address","type":"string"}
      ],
      "primaryKey":["index"],
      "pandas_version":"0.20.0"},
      "data":[
        {"index":0,"name":"邵帆","job":"机修工","address":"广西壮族自治区建国市花溪合肥街 t 座 303979"},
        {"index":1,"name":"何丹丹","job":"系统测试","address":"湖北省沈阳市清城杨路 b 座 435741"},
        {"index":2,"name":"范佳","job":"汽车修理工","address":"四川省建县丰都李街 e 座 707065"},
        {"index":3,"name":"王云","job":"服装\/纺织\/皮革工艺师","address":"内蒙古自治区长沙市双滦巢湖路 D 座 438460"},
        {"index":4,"name":"赵玉珍","job":"ERP 技术开发","address":"吉林省玉华市崇文杨路 l 座 846818"},
        {"index":5,"name":"倪阳","job":"销售行政专员","address":"甘肃省欢县怀柔重庆路 H 座 950331"},
        {"index":6,"name":"成莉","job":"麻醉医生","address":"广西壮族自治区文市华龙余路 q 座 603504"},
        {"index":7,"name":"任斌","job":"其他","address":"湖北省上海县东城长沙街 D 座 331924"},
        {"index":8,"name":"赵霞","job":"医疗器械注册","address":"北京市燕市双滦澳门路 I 座 647751"},
        {"index":9,"name":"黄莹","job":"其他","address":"福建省惠州县涪城王街 j 座 216044"}
      ]
    }

HDF5

read_hdf 与 to_hdf

HDF5 文件的读取和存储需要指定一个键,值为要存储的 DataFrame

pandas.read_hdf(path_or_buf,key =None,**kwargs)

从 h5 文件当中读取数据

  • path_or_buffer:文件路径
  • key:读取的键
  • return:Theselected object

需要安装安装 tables 模块避免不能读取 HDF5 文件

shell
pip install tables

文件操作

  • 存储文件

    python
    df.to_hdf("table.h5", key="table")
  • 读取文件

    python
    day_close = pd.read_hdf("day_close.h5")
    
    print(day_close)

再次读取的时候, 需要指定键的名字

python
new_close = pd.read_hdf("./data/test.h5", key="day_close")

注意:优先选择使用 HDF5 文件存储

  • HDF5 在存储的时候支持压缩,使用的方式是 blosc,这个是速度最快 的也是 pandas 默认支持的
  • 使用压缩可以 提磁盘利用率,节省空间
  • HDF5 还是跨平台的,可以轻松迁移到 hadoop 上面