处理数据,大数据甚至更大数据的 17 种策略

如何处理大数据和真正的大数据?

本文最初发表在 Towards Data Science 博客,经原作者 Jeff Hale 授权,InfoQ 中文站翻译并分享。

处理大数据可能很棘手。不会有人喜欢“内存不足”的错误提示。也不会有人愿意等待代码运行。更别说会有人乐意抛弃 Python。

如果你遇到这些问题,请不要绝望!我将在本文中为你提供一些技巧,并介绍一些即将问世的库,帮助你高效地处理大数据。我还会为你提供解决方案,解决那些无法适合内存的代码问题。而这一切都将会在 Python 中进行。

Python是最流行科学和数值计算编程语言。对于清理代码和探索性数据分析来说,Pandas是最受欢迎的。

在 Python 中使用 Pandas,可以让你处理比 Microsoft Excel 或 Google Sheets 更多的数据。

SQL 数据库在存储数据方面非常流行,但是 Python 生态系统在表达性、测试性、可再现性以及快速执行数据分析、统计和机器学习的能力方面,比 SQL 有很多优势。

不幸的是,如果你是在本地工作的话,那么,Pandas 所能处理的数据量将会受到你机器上的物理内存容量限制。但如果你在云端中工作,更多的内存需求又意味着需要耗费更多的资金。

无论你的代码在哪里运行,你都希望操作能够快速进行,这样你就可以完成任务!

总是要做的事情

如果你听说过或看到过关于加速代码的建议,那么你一定看到过警告:不要过早优化!

诚然 ,这是一条好建议。但懂得一些技巧也是很聪明的做法,这样你才能写出干净、快速的代码。

对于任何规模的数据集来说,下面三种做法都是良好的编码实践。

  1. 尽可能避免嵌套循环。点击此处可以参阅大 O 符号(Big-O notation)和算法分析的简单分析。一个 for 循环嵌套在另一个 for 循环里,一般会导致多项式时间的计算。如果你有不止几个项目要搜索的话,那么就需要等上一段时间。请看此处的图表和解释。
  2. 在 Python 中尽可能使用列表推导(List comprehension)(以及字典推导(Dist comprehension))。按需创建列表比加载列表的 append 属性并将其作为函数反复调用要快:这要感谢 Stack Overflow Answer(译注:Stack Overflow 网站的一款 App,Stack Overflow 是一个程序设计领域的问答网站)。然而,一般来说,不要为了速度而牺牲清晰度,所以在嵌套列表推导务必要小心。
  3. 在 Pandas,使用内置的函数向量化。其原理其实和字典推导的原因是一样的。一次将一个函数应用于整个数据结构比重复调用一个函数要快得多。

如果你发现自己正在申请,请想想你是否真的需要这样做。它将会遍历行或列。向量化方法通常速度更快,代码更少,因此它们是一个双赢的方法。

要避免使用其他在数据上循环的 Pandas Series 和 DataFrame 方法:applymapitterrowsittertuples。在 DataFrame 上使用replace方法,而不是任何其他选项,这样可以节省大量时间。

请注意,这些建议可能不适用于非常少量的数据,但在这种情况下,风险很低,所以谁在乎呢?

这就涉及到我们最重要的规则

如果可以,就继续用 Pandas。这是快乐的源泉。

如果你没有问题,也不希望数据膨胀,就不要担心这些问题。但在某些时候,你会遇到一个大数据集,然后你会想知道该怎么做。让我们来看一些技巧。

处理相当大的数据(大约数百万行)

  1. 如果你要做机器学习,就用你的数据子集来探索、清理,构建一个基线模型。快速解决 90% 的问题,节省时间和资源。这个技巧可以帮你节省很多时间。
  2. 在读取 DataFrame 时,只用usecols参数加载你需要的列。记住,更少的数据输入意味着胜利!
  3. 有效地利用 dtype。将数值列向下转换为对pandas.to_numeric()有意义的最小 dtypes。将基数较低的列(只有几个值)转换为分类 dtype。请参阅这个关于高效 dtype 的Pandas 指南
  4. 在 Scikit-learn 将模型训练并行化,学习尽可能使用更多的处理核心。默认情况下,Scikit-learn 只使用 CPU 的一个核心。许多计算机的 CPU 有 4 个或更多的核心。在使用 GridSearchCV 和许多其他类进行交叉验证时,通过传递参数n_jobs=-1,可以将它们全部用于可并行化的任务。
  5. 将 Pandas DataFrame 保存为 feather 或 pickle 格式,以加快读写速度。感谢 Martin Skarzynski,因为他提供了证据和代码的链接
  6. 使用pd.eval加快 Pandas 的操作。将你常用的代码以字符串形式传递给函数。它的操作速度更快。下面有一个测试图表,DataFrame 为 100 列。

df.querypd.eval基本相同,但它是作为 DataFrame 方法,而不是顶级 Pandas 函数。

由于存在一些问题,请注意查看文档。

Pandas 在幕后使用的是 Numexpr。Numexpr 还可以与 NumPy 一起工作。向 Chris Conlan 致敬,感谢他的著作《Fast Python》(《快速 Python》),正是这本书,我才知道了 Numexpr。Chris 这本书是一本学习如何加速 Python 代码的优秀读物。

处理真正的大数据(大约数千万行以上)

  1. 使用Numba。如果你在做数学计算,Numba 能给你带来极大的速度提升。安装 Numba 并导入它。然后,当你需要在 NumPy 数据上进行循环,且不能使用向量化方法时,就使用@numba.jit装饰器函数。它只对 NumPy 数据有效。在 Pandas DataFrame 上使用.to_numpy()将其转换为 NumPy 数组。
  2. 在有意义的时候使用SciPy 稀疏矩阵。Scikit-learn 通过一些转换器(如 CountVectorizer)自动输出稀疏数组。当数据主要为 0 或缺少值时,可以将列转换为 Panda 中的稀疏 dtype。要了解更多内容请点击此处
  3. 使用 Dask 将数据集的读取并行化为 Pandas 的数据块。Dask 还可以跨多台机器执行并行化数据操作。它模仿了 Panda 和 NumPy API 的一个子集。Dask_ML是一个姊妹包,用于跨多台机器并行化机器学习算法。它模仿了 Scikit-learn API。与其他流行的机器学习库如 XGBoost、LightGBM、PyTorch 和 TensorFlow 很好地结合在一起。
  4. 不管有没有 GPU,都可以使用 PyTorch。正如我在这篇关于排序的文章中所发现的那样,在 GPU 上使用 PyTorch 可以大大提高速度。

未来处理大数据需要注意/尝试的事项

以下三个方案是截止 2020 年年中的前沿方案。预计将会出现配置问题和早期 API。如果你是在本地 CPU 上工作,这些方案不太可能满足你的需求。但它们看起来都很有前途,值得关注。

  1. 你能使用很多 CPU 核心吗?你的数据是否超过 32 列(到 2020 年年中开始是必需的)?然后考虑一下Modin。它模仿 Pandas 的一个子集,以加快对大型数据集的操作。它在幕后使用的是 Apache Arrow(通过 Ray)或 Dask。Dask 后端是实验性的。在我的测试中,有些事情并不是很快,例如,从 NumPy 数组读取数据就很慢,并且内存管理也是一个问题。
  2. 你可以使用 Jax 代替 NumPy。Jax 是 Google 开源的一款非常前沿的产品。它通过以下五个底层工具来加速操作:autograd、XLA、JIT、向量化器和并行化器。它可以在 CPU、GPU 或 TPU 上工作,并且可能比使用 PyTorch 或 TensorFlow 来获得速度提升更简单。 Jax 也适用于深度学习。它目前有 NumPy 版本,但尚未提供 Pandas 版本。不过,你可以将 DataFrame 转换为 TensorFlow 或 NumPy,然后再使用 Jax。请点击这里以了解更多内容。
  3. Rapids cuDF在 GPU 上使用 Apache Arrow,并带有类似 Pandas 的 API。这是一个 NVIDIA 开源的 Python 包。Rapids 与 Dask 配合得很好,所以你可以让多个 GPU 并行处理数据。对于最大的工作复杂,它应该能带来一个很好的提升。

其他关于代码速度和大数据的知识

计时操作

如果你想在 Jupyter Notebook 中进行计时操作,你可以使用%time%%timeit魔法命令。它们都在单行或真个代码单元中工作。

%time运行一次,而%%timeit运行代码多次(默认值为 7)。一定要查看文档,了解其中的微妙之处。

如果你在脚本或 Notebook 中,可以导入时间模块,检查运行某些代码前后的时间,并找出差异。

在进行测试时间时,请注意不同的机器和软件版本可能会导致差异。如果要重复测试的话,缓存有时候会产生误导。正如所有的实验一样,要尽可能保持一切不变。

存储大数据

GitHub 的最大文件大小为100MB。如果你想使用 GitHub 对大文件进行版本化,你可以使用Git Large File Storage(Git 大文件存储)扩展。

除非你愿意,否则请确保你没有将文件自动上传到 Dropbox、iCloud 或其他自动备份服务。

想了解更多吗?

Pandas 文档中,有关于提高性能扩展到大型数据集的部分。本文其中一些想法就是根据这些章节改编而来。

总结

你已经了解了如何编写更快的代码,你也了解了如何处理大数据和真正的大数据。最后,你还了解到了一些新出的库,它们在处理大数据方面可能会继续变得越来越流行。

我希望本文能够对你有所帮助。

作者介绍:

Jeff Hale,技术撰稿人,撰写数据科学相关的文章,如 Python、SQL、Docker 和其他技术主题。并维护数据科学资源邮件列表:https://dataawesome.com

原文链接:

https://towardsdatascience.com/17-strategies-for-dealing-with-data-big-data-and-even-bigger-data-283426c7d260

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/l728jSHFayF2hIz5Byac
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券