Python 数据分析笔记数据的检索加工与存储

数据的检索加工与存储

1. 利用 Numpy 和 pandas 对 CSV 文件进行写操作

对 CSV 文件进行写操作, numpy 的 savetxt()函数是与 loadtxt()相对应的一个函数, 他能以诸如 CSV 之类的区隔型文件格式保存数组:

np.savetxt(np.csv, a, fmt = % .2f, delimiter = , , header = "#1,#2,#3,#4")

上面的函数调用中, 我们规定了用以保存数组的文件的名称数组可选格式间隔符 (默认为空格符) 和一个可选的标题

利用随机数组来创建 pandas DataFrame, 如下:

df=pd.DataFrame(a)

利用 pandas 的 to_csv()方法可以为 CSV 文件生成一个 DataFrame

df.to_csv(pd.csv, float_format = % .2f, na_rep = "NAN!")

对于这个方法, 我们需要提供文件名类似于 Numpy 的 savetxt()函数的格式化参数的可选格式串和一个表示 NaN 的可选字符串

2.Numpy.npy 与 pandas DataFrame

大部分情况下, 用 CSV 格式来保存文件是不错的主意, 因为大部分程序设计语言和应用程序都能处理这种格式, 所以交流起来非常方便然而, 这种格式有一个缺陷, 就是它的存储效率不是很高, 原因是 CSV 及其他纯文本格式中含有大量空白符; 而后来发明的一些文件格式, 如 zipbzip 和 gzip 等, 压缩率则有了显著提升importnu

mpyasnp
importpandasaspd
fromtempfileimportNamedTemporaryFile
fromos.pathimportgetsize
np.random.seed(42)
a=np.random.randn(365,4)
tmpf=NamedTemporaryFile()
np.savetxt(tmpf,a,delimiter=,)
print("Size CSV file",getsize(tmpf.name))
tmpf=NamedTemporaryFile()
np.save(tmpf,a)
tmpf.seek(0)
loaded=np.load(tmpf)
print("shape",loaded.shape)
print("Size .npy file",getsize(tmpf.name))
df=pd.DataFrame(a)
df.to_pickle(tmpf.name)
print("Size pickled dataframe",getsize(tmpf.name))
print("DF from pickle\n",pd.read_pickle(tmpf.name))

Numpy 为自己提供了一种专用的格式, 称为. 女朋友, 可以用于存储 Numpy 数组在进一步说明这种格式之前, 我们先来生成一个 365×4d 的 Numpy 数组, 并给各个元素填充上随机值这个数组可以看成是一年中 4 个随机变量的每日观测值的模拟这里我们使用 Python 标准的 NamedTemporaryFile 来存储数据, 这些临时文件随后会自动删除

下面将该数组存入一个 CSV 文件, 并检查其大小, 代码如下:tmpf=NamedTemporaryFile()

np.savetxt(tmpf,a,delimiter=,)
print("Size CSV file",getsize(tmpf.name))

下面首先以 Numpy.npy 格式来保存该数组, 随后载入内存, 并检查数组的形状以及该. npy 文件的大小, 具体代码如下所示:tmpf=NamedTemporaryFile()

np.save(tmpf,a)
tmpf.seek(0)
loaded=np.load(tmpf)
print("shape",loaded.shape)
print("Size .npy file",getsize(tmpf.name))

为了模拟该临时文件的关闭与重新打开过程, 我们在上面的代码中调用了 seek()函数数组的形状以及文件大小如下所示:Shape(365,4)

Size.npy file11760

不出所料,.npy 文件的大小只有 CSV 文件的 1/3 左右实际上, 利用 Python 可以存储任意复杂的数据结构也可以序列化格式来存储 pandas 的 DataFrame 或者 Series 数据结构

提示:

在 Python 中, pickle 是将 Python 对象存储到磁盘或其他介质时采用的一种格式, 这个格式化的过程叫做序列化(pickling). 之后, 我们可以从存储器中重建该 Python 对象, 这个逆过程称为反序列化(unpickling).

首先用前面生成的 Numpy 数组创建一个 DataFrame, 接着用 to_pickle()方法将其写入一个 pickle 对象中, 然后用 read_pickle()函数从这个 pickle 对象中检索该 DataFrame:df=pd.DataFrame(a)

df.to_pickle(tmpf.name)
print("Size pickled dataframe",getsize(tmpf.name))
print("DF from pickle\n",pd.read_pickle(tmpf.name))

该 DataFrame 经过序列化后, 尺寸略大于. npy 文件

3. 使用 PyTables 存储数据

层次数据格式 (HDF) 是一种存储大型数值数据的技术规范, 起源于超级计算社区, 目前已经成为一种开放的标准这里用 HDF5, 该版本仅仅通过组 (group) 和数据集 (dataset) 这两种基本结构来组织数据数据集可以是同类型的多维数组, 而组可以用来存放其他组或者数据集这里的组跟层次式文件系统中的目录非常像

HDF5 最常见的两个主要 Python 程序库是:

1.h5y

2.PyTables

本例中使用的是 PyTables 不过, 这个程序库需要用到一些依赖项, 比如:

1.Numpy

2.numexpr: 该程序包在计算包含多种运算的数组表达式时, 其速度要比 Numpy 快许多倍

3.HDF5: 如果使用 HDF5 的并行版本, 则还需要安装 MPI.

据 Numexpr 自称, 它在某些方面的运算速度要比 Numpy 快得多, 因为它支持多线程, 并且自己得虚拟机是 C 语言实现得

此外, 我们需要生成一些随机数, 并用它们来给一个 Numpy 数组赋值下面创建一个 HDF5 文件, 并把这个 Numpy 数组挂载到根结点上fromtempfileimportNamedTemporaryFile

importnumpyasnp
fromos.pathimportgetsize
a=np.random.randn(365,4)
tmpf=NamedTemporaryFile()
h5file=tables.openfile(tmpf.name,mode=w,title="Numpy Array")
root=h5file.root
h5file.createArray(root,"array",a)
h5file.close()
# 读取这个 HDF5, 并显示文件大小
h5file=tables.openfile(tmpf.name,"r")
print(getsize(tmpf.name))
通过遍历取为里面的数据fornodeinh5file.iterNodes(h5file.root):
b=node.read()
print(type(b),b.shape)

4.Pandas DataFrame 与 HDF5 仓库之间的读写操作

HDFStore 类可以看作是 pandas 中负责 HDF5 数据处理部分的一种抽象借助一些随机数据和临时文件, 可以很好地展示这个类地功能特性, 具体步骤如下所示:

将临时文件地路径传递给 HDFStore 的构造函数, 然后创建一个仓库:store=pd.io.pytables.HDFStore(tmpf.name)

print(store)

上述代码将打印输出该仓库的文件路径及其内容, 不过, 此刻他还没有任何内容

HDFStore 提供了一个类似字典类型的接口, 如我们可以通过 pandas 中 DataFrame 的查询键来存储数值为了将包含随机数据的一个 DataFrame 存储到 HDFStore 中, 可以使用下列代码:store[df]=df

print(store)

我们可以用三种方式来访问 DataFrame, 分别是: 使用 get()方法访问数据, 利用类似字典的查询键访问数据, 或者使用点运算符号来访问数据:print("Get",store.get(df).shape)

print("Lookup",store[df].shape)

print("Dotted",store.df.shape)

该 DataFrame 的形状同样也可以通过 3 种不同的方式进行访问

为了删除仓库中的数据, 我们既可以使用 remove()方法, 也可以使用 del 运算符当然, 每个数据只能删除一次

del store[df]

属性 is_open 的作用是指出仓库是否处于打开状态为了关闭一个仓库, 可以调用 close()方法下面代码展示关闭仓库的方法, 并针对仓库的状态进行了相应的检查:print("Before close",store.is_open)

store.close()

print("After close",store.is_open)

为读写 HDF 数据, pandas 还提供了两种方法: 一种是 DataFrame 的 to_hdf()方法; 另一种是顶级的 read_hdf()函数df.to_hdf(tmpf.name,data,format=table)

print(pd.read_hdf(tmpf.name,data,where=[index>363]))

用于读写操作的应用程序接口的参数包括: 文件路径仓库中组的标识符以及可选的格式串这里的格式有两种: 一种是固定格式; 一种是表格格式固定格式的优点是速度要更快一些, 缺点是无法追加数据, 也不能进行搜索表格格式相当于 PyTables 的 Table 结构, 可以对数据进行搜索和选择操作

5. 使用 pandas 读写 Excel 文件

现实中许多重要数据都是以 Excel 文件的形式存放的当然, 如果需要, 也可以将其转换为可移植性更高的诸如 CSV 之类的格式不过, 利用 Python 来操作 Excel 文件会更加方便在 Python 的世界里, 为实现同一目标的项目通常不止一个, 如提供 Excel I/O 操作功能的项目就是如此只要安装了这些模块, 就能让 pandas 具备读写 Excel 文件的能力, 只是这些方面的说明文档不是很完备, 其原因是 pandas 依赖的这些项目往往各自为战, 并且发展极为迅猛这些 pandas 程序包对于 Excel 文件也很挑剔, 要求这些文件的后缀必须是. xls 或者. xlsx; 否则会报错

模块 openpyxl 源于 PHPExcel, 它提供了针对. xlsx 文件的读写功能

模块 xlsxwriter 也需要读取. xlsx 文件

模块 xlrd 能用来析取. xls 和. xlsx 文件中的数据下面, 我们先来生成用于填充 pandas 中 DataFrame 的随机数, 然后用这个 DataFrame 创建一个 Excel 文件, 接着再用 Excel 文件重建 DataFrame, 并通过 mean()方法来计算其平均值对于 Excel 文件的工作表, 我们既可以为其指定一个从 0 开始计数的索引, 也可以为其规定一个名称importnumpyasnp

importpandasaspd
fromtempfileimportNamedTemporaryFile
np.random.seed(42)
a=np.random.randn(365,4)
tmpf=NamedTemporaryFile(suffix=.xlsx)
df=pd.DataFrame(a)
print(tmpf.name)
df.to_excel(tmpf.name,sheet_name=RandomData)
print("Means\n",pd.read_excel(tmpf.name,RandomData).mean())

通过 to_excel()方法创建 Excel 文件, 有用顶级 read_excel()函数来重建 DataFrame

6. 使用 pandas 读写 JSON

pandas 提供的 read_json()函数, 可以用来创建 pandas Series 或者 pandas DataFrame 数据结构importpandasaspd

json_str={"country":"Netherlands","dma_code":"0","timezone":"Europe\/Amsterdam","area_code":"0","ip":"46.19.37.108","asn":"AS196752","continent_code":"EU","isp":"Tilaa V.O.F.","longitude":5.75,"latitude":52.5,"country_code":"NL","country_code3":"NLD"}
data=pd.read_json(json_str,typ=series)
print("Series\n",data)
data["country"]="Brazil"
print("New Series\n",data.to_json())

调用 read_json()函数时, 既可以向其传递一个 JSON 字符串, 也可以为其指定一个 JSON 文件的路径上面的例子中, 我们是利用 JSON 字符串来创建 pandas Series

并且再次修改 country 的值, 并用 to_json()方法将其从 pandas Series 转换为 JSON 字符串