利用Pandas和SQLite提升超大数据的读取速度

栏目: IT技术 · 发布时间: 4年前

内容简介:让我们想象,你有一个非常大的数据集,以至于读入内存之后会导致溢出,但是你想将它的一部分用Pandas进行处理,如果你在某个时间点只是想加载这个数据集的一部分,可以使用分块方法。如果把数据集分为若干部分之后,分别加载进来,最终还是会很慢。此时的解决方法,就是创建一个可供搜索的索引,使用SQLite就能轻松解决。

让我们想象,你有一个非常大的数据集,以至于读入内存之后会导致溢出,但是你想将它的一部分用Pandas进行处理,如果你在某个时间点只是想加载这个数据集的一部分,可以使用分块方法。

如果把数据集分为若干部分之后,分别加载进来,最终还是会很慢。

此时的解决方法,就是创建一个可供搜索的索引,使用 SQLite 就能轻松解决。

第一个方法:分块

来设想一个具体的示例:你要参加某个竞选,为此,你找到了一个CSV文件,里面包含你所在城市每个选民的信息。于是乎你派人去挨门挨户地拜访,邀请特定街道的所有登记选民参与投票。

现在,Pandas的DataFrame对象中有索引,但是必须要将数据读入内存,然而CSV文件太大了,内存无法容纳,于是,你想到,可以只载入你关注的记录。

这就是第一个方法,进行分块。

import pandas as pd 
 
def get_voters_on_street(name):  
    return pd.concat(  
       df[df["street"] == name] for df in  
       pd.read_csv("voters.csv", chunksize=1000)  
    )  

以分块的方式加载CSV文件,并且按照街道名称进行筛选,然后将得到记录并为一体。

虽然逐行加载,但是关注的是比较小的子集,所以需要一些开销。比如,对于只有70k的数据集,在我的计算机上执行上面的函数,需要574ms。2018年纽约市有460万登记选民,挨个街道查找,需要30s。

如果我们只做一次,没关系,如果需要反复做,这种方法并不是最佳。

创建索引对象

索引就是摘要,有这样一种说法:如果你关心它,就能在这里找到大量数据。在我们的示例中,我们想根据街道名称创建索引,于是就可以快速加载投票者所在的街道了。

如果你担心索引数据也会超出内存,那么数据库则能作为保存它们的容器,例如PostgreSQL、 MySQL 等数据库都能实现。哦,你不喜欢安装和维护那些讨厌的服务,好吧,SQLite应运而生了。

SQLite是一个功能齐全的关系型数据库,它能够像其它数据库一样运行,但是不需要服务器。Pyhton默认就支持这种数据库。SQLite将数据保存在独立的文件中,你必须管理一个SQLite数据文件,而不是CSV文件了。

用SQLite存储数据

下面演示一下如何用Pandas操作SQLite:

1. 将数据载入SQLite,并创建索引

SQLite数据库能够保存多张数据表,首先将voters.csv文件的数据载入SQLite,并保存为voters.sqlite文件,在这个文件中,我们创建一个名为voters的表。

接下来,在SQLite中创建街道的索引。

只需如下操作:

import sqlite3 
 
# Create a new database file: 
db = sqlite3.connect("voters.sqlite") 
 
# Load the CSV in chunks: 
for c in pd.read_csv("voters.csv", chunksize=1000): 
    # Append all rows to a new database table, which 
    # we name 'voters': 
    c.to_sql("voters", db, if_exists="append") 
# Add an index on the 'street' column: 
db.execute("CREATE INDEX street ON voters(street)")  
db.close() 

虽然我们只创建单个索引,但我们还可以在其他列或多个列上创建其他索引,从而允许我们使用这些列快速搜索数据库。

利用Pandas和SQLite提升超大数据的读取速度

2. 重写查询函数

现在,所有数据都已经载入SQLite,我们可以按照街道进行检索了。

def get_voters_for_street(street_name): 
    conn = sqlite3.connect("voters.sqlite") 
    q = "SELECT * FROM voters WHERE street = ?" 
    values = (street_name,) 
    return pd.read_sql_query(q, conn, values) 

执行上述函数,SQLite只加载与查询匹配的行,并其通过Pandas将它们保存为DataFrame对象。

50多倍的加速

那个CSV文件供给70,000行记录,原来花费了574ms,现在只用了10ms。

提速50多倍,这是因为,只需要加载我们关心的行,而不是CSV文件中的每一行。


以上所述就是小编给大家介绍的《利用Pandas和SQLite提升超大数据的读取速度》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机操作系统

计算机操作系统

/ 西安电子科技大学出版 / 1984-11 / 19.60元

一起来看看 《计算机操作系统》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具