软件应用 | 教你几招,Pandas 轻松处理超大规模数据
本文转载自公众号机器学习算法与python学习
作者:Sara A. Metwalli
译者:盖磊
可能的解决方案
投资解决
新购有能力处理整个数据集,具有更强 CPU 和更大内存的计算机。或是去租用云服务或虚拟内存,创建处理工作负载的集群。
耗时解决
如果内存不足以处理整个数据集,而硬盘的容量要远大于内存,此时可考虑使用硬盘存储数据。但使用硬盘管理数据会大大降低处理性能,即便是 SSD 也要比内存慢很多。
第一种技术:压缩
无损压缩
加载特定的数据列
import pandas as pd
data = pd.read_csv("https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv")
data.sample(10)
# 加载所需软件库 Import needed library
import pandas as pd
# 数据集
csv = "https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv"
# 加载整个数据集
data = pd.read_csv(csv)
data.info(verbose=False, memory_usage="deep")
# 创建数据子集
df = data[["county", "cases"]]
df.info(verbose=False, memory_usage="deep")
# 加速所需的两列数据
df_2col = pd.read_csv(csv , usecols=["county", "cases"])
df_2col.info(verbose=False, memory_usage="deep")
操作数据类型
int8 存储值的范围是 -128 到 127; int16 存储值的范围是 -32768 到 32767; int64 存储值的范围是 -9223372036854775808 到 9223372036854775807。
稀疏列
如果数据集的一或多个列中具有大量的 NaN 空值,那么可以使用 稀疏列表示 降低内存使用,以免空值耗费内存。
假定州名这一列存在一些空值,我们需要跳过所有包含空值的行。该需求可使用 pandas.sparse 轻松实现(译者注:原文使用 Sparse Series,但在 Pandas 1.0.0 中已经移除了 SparseSeries)。
有损压缩
如果无损压缩并不满足需求,还需要进一步压缩,那么应该如何做?这时可使用有损压缩,权衡内存占用而牺牲数据百分之百的准确性。
有损压缩有两种方式,即修改数值和抽样。
修改数值:有时并不需要数值保留全部精度,这时可以将 int64 截取为 int32 甚至是 int16。
抽样:如果需要确认某些州的新冠病例数要高于其它州,可以抽样部分州的数据,查看哪些州具有更多的病例。这种做法是一种有损压缩,因为其中并未考虑到所有的数据行。
第二种技术:数据分块(chunking)
另一个处理大规模数据集的方法是数据分块。将大规模数据切分为多个小分块,进而对各个分块分别处理。在处理完所有分块后,可以比较结果并给出最终结论。
本文使用的数据集中包含了 1923 行数据。
假定我们需要找出具有最多病例的州,那么可以将数据集切分为每块 100 行数据,分别处理每个数据块,从这各个小结果中获取最大值。
本节代码片段如下:
# 导入所需软件库
import pandas as pd
# 数据集
csv = "https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv"
# 循环处理每个数据块,获取每个数据块中的最大值
result = {}
for chunk in pd.read_csv(csv, chunksize=100):
max_case = chunk["cases"].max()
max_case_county = chunk.loc[chunk[ cases ] == max_case, county ].iloc[0]
result[max_case_county] = max_case
# 给出结果
print(max(result, key=result.get) , result[max(result, key=result.get)])
第三种技术:索引
索引 vs 分块
import sqlite3
csv = "https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv"
# 创建新的数据库文件
db = sqlite3.connect("cases.sqlite")
# 按块加载 CSV 文件
for c in pd.read_csv(csv, chunksize=100):
# 将所有数据行加载到新的数据库表中
c.to_sql("cases", db, if_exists="append")
# 为“state”列添加索引
db.execute("CREATE INDEX state ON cases(state)")
db.close()
小 结
处理大规模数据集时常是棘手的事情,尤其在内存无法完全加载数据的情况下。一些解决方案或是耗时,或是耗费财力。毕竟增加资源是最简单直接的解决方案。
但是在资源受限的情况下,可以使用 Pandas 提供的一些功能,降低加载数据集的内存占用。其中的可用技术包括压缩、索引和数据分块。
点击阅读原文,进入CCAD数据库
·END·
星标⭐我们不迷路!
想要文章及时到,文末“在看”少不了!
点击搜索你感兴趣的内容吧
往期推荐
数据Seminar
这里是大数据、分析技术与学术研究的三叉路口
推荐丨青酱
欢迎扫描👇二维码添加关注