问答中心分类: MONGODB使用 pandas 的“大数据”工作流程
0
匿名用户 提问 2月 前

关闭。这个问题不符合堆栈溢出指南.它目前不接受答案。

我们不允许提出有关书籍、工具、软件库等建议的问题。您可以编辑问题,以便可以用事实和引用来回答它。

关闭9 个月前.

社区审核是否重开这个问题9 个月前并将其关闭:

原始关闭原因未解决

改进这个问题

在学习熊猫的过程中,我已经尝试了好几个月来想出这个问题的答案。我在日常工作中使用 SAS,它的核心支持非常棒。然而,由于许多其他原因,SAS 作为一个软件是可怕的。
有一天,我希望用 python 和 pandas 代替我对 SAS 的使用,但我目前缺乏大型数据集的核心工作流程。我不是在谈论需要分布式网络的“大数据”,而是说文件太大而无法放入内存但小到足以放入硬盘驱动器。
我的第一个想法是使用HDFStore将大型数据集保存在磁盘上并仅将我需要的部分拉入数据帧进行分析。其他人提到 MongoDB 是一种更易于使用的替代方案。我的问题是这样的:
完成以下任务的最佳实践工作流程是什么:

  1. 将平面文件加载到永久的磁盘数据库结构中
  2. 查询该数据库以检索数据以输入 pandas 数据结构
  3. 在 Pandas 中操作片段后更新数据库

现实世界的例子将不胜感激,尤其是任何在“大数据”上使用 pandas 的人。
编辑——我希望它如何工作的一个例子:

  1. 迭代地导入一个大的平面文件并将其存储在一个永久的磁盘数据库结构中。这些文件通常太大而无法放入内存。
  2. 为了使用 Pandas,我想读取可以放入内存的这些数据的子集(通常一次只有几列)。
  3. 我将通过对选定列执行各种操作来创建新列。
  4. 然后我必须将这些新列附加到数据库结构中。

我正在尝试找到执行这些步骤的最佳实践方式。阅读有关 pandas 和 pytables 的链接似乎附加一个新列可能是一个问题。
编辑——具体回答杰夫的问题:

  1. 我正在建立消费者信用风险模型。数据种类包括电话、SSN、地址特征;财产价值;犯罪记录、破产等贬损信息……我每天使用的数据集平均有近 1,000 到 2,000 个混合数据类型的字段:数字和字符数据的连续变量、名义变量和有序变量。我很少追加行,但我确实执行了许多创建新列的操作。
  2. 典型的操作包括使用条件逻辑将多个列组合成一个新的复合列。例如,if var1 > 2 then newvar = 'A' elif var2 = 4 then newvar = 'B'.这些操作的结果是我的数据集中每条记录的新列。
  3. 最后,我想将这些新列附加到磁盘数据结构中。我将重复第 2 步,使用交叉表和描述性统计数据探索数据,试图找到有趣、直观的建模关系。
  4. 一个典型的项目文件通常约为 1GB。文件被组织成这样一种方式,其中一行包含消费者数据的记录。对于每条记录,每一行都有相同数量的列。情况将永远如此。
  5. 在创建新列时,我很少会按行进行子集化。但是,在创建报告或生成描述性统计数据时,对我来说,对行进行子集化是很常见的。例如,我可能想为特定业务线创建一个简单的频率,例如零售信用卡。为此,除了我想要报告的任何列之外,我只会选择那些业务范围 = 零售的记录。但是,在创建新列时,我会提取所有数据行,并且只提取操作所需的列。
  6. 建模过程要求我分析每一列,寻找与某些结果变量的有趣关系,并创建描述这些关系的新复合列。我探索的专栏通常是在小范围内完成的。例如,我将专注于一组 20 列仅处理财产价值的列,并观察它们与贷款违约的关系。一旦探索了这些并创建了新的专栏,我就会转到另一组专栏,比如大学教育,然后重复这个过程。我正在做的是创建候选变量来解释我的数据与某些结果之间的关系。在这个过程的最后,我应用了一些学习技术,从这些复合列中创建一个方程。

我很少会向数据集添加行。我几乎总是会创建新列(统计/机器学习用语中的变量或特征)。

denis 回复 2月 前

核心尺寸/全尺寸的比率是 1%、10% 吗?有没有关系——如果你可以将 cols 压缩到 int8,或者过滤掉嘈杂的行,那会改变你的计算思考循环从几小时到几分钟吗? (同时添加标签大数据。)

denis 回复 2月 前

尽可能存储 float32 而不是 float64 和 int8,应该微不足道(虽然不知道 float64 内部有哪些工具/功能)

denis 回复 2月 前

你能把你的任务分成几块工作吗?

denis 回复 2月 前

一个不错的 2019 年解决方案,可以对不适合内存的“中等”数据进行类似 pandas 的操作黎明

denis 回复 2月 前

在您刚开始时,您可能需要考虑查看 python+pandas 的替代方案。考虑一下 Python 是一种通用编程语言(不是用于数据处理和分析的 DSL)并且 pandas 是一个基于此的库的事实。我会考虑看 R 或 kdb。

denis 回复 2月 前

duckdb 正在逐渐成为在单台机器上处理中型数据集的一个很好的替代方案。

15 Answers
0
user1827356 回答 2月 前

我认为上面的答案缺少一种我发现非常有用的简单方法。
当我有一个文件太大而无法加载到内存中时,我会将文件分成多个较小的文件(按行或按列)
示例:如果有 30 天的价值约 30GB 的交易数据,我每天将其分解为约 1GB 大小的文件。我随后分别处理每个文件并在最后汇总结果
最大的优点之一是它允许并行处理文件(多个线程或进程)
另一个优点是文件操作(如示例中的添加/删除日期)可以通过常规 shell 命令完成,这在更高级/复杂的文件格式中是不可能的
这种方法并不涵盖所有场景,但在很多场景中都非常有用

zelusp 回复 2月 前

同意。随着所有的炒作,很容易忘记这一点命令行工具可以比 Hadoop 集群快 235 倍

amin_nejad 回复 2月 前

更新链接:adamdrake.com/…

0
Private 回答 2月 前

现在,在问题发生两年后,“核心外”熊猫等效:黎明.太棒了!虽然它不支持所有 pandas 功能,但你可以用它走得很远。更新:在过去的两年中,它一直得到维护,并且有大量用户社区与 Dask 合作。
而现在,在这个问题发生四年后,还有另一个高性能的“核心外”熊猫相当于瓦克斯.它“使用内存映射、零内存复制策略和惰性计算来获得最佳性能(不浪费内存)。”它可以处理数十亿行的数据集,并且不会将它们存储到内存中(甚至可以对次优硬件进行分析)。

gies0r 回复 2月 前

根据您的数据,查看一下是有意义的pystore.它依赖于dask.

Michele Piccolini 回复 2月 前

它总是“脱离核心”吗? (即不是 RAM 密集型?)。如果您手头没有集群,那么 Dask 不是一个好的解决方案,恕我直言。引自Dask 文档本身“如果您希望管理 TB 或更少的表格格式 CSV 或 JSON 数据,那么您应该忘记 Spark 和 Dask,而使用 Postgres 或 MongoDB。”

0
rjurney 回答 2月 前

如果您的数据集在 1 到 20GB 之间,您应该获得一个具有 48GB RAM 的工作站。然后 Pandas 可以将整个数据集保存在 RAM 中。我知道这不是您在这里寻找的答案,但是在具有 4GB RAM 的笔记本电脑上进行科学计算是不合理的。

william_grisaitis 回复 2月 前

“在 4GB RAM 的笔记本上做科学计算是不合理的” 定义合理。我认为UNIVAC 会采取不同的观点。arstechnica.com/tech-policy/2011/09/…

ansonw 回复 2月 前

同意!尝试继续在内存中工作,即使它预先花费 $$。如果您的工作带来了财务回报,那么随着时间的推移,您将通过提高效率来弥补开支。

Yaroslav Nikitenko 回复 2月 前

在具有 48GB RAM 的工作站上进行科学计算是不合理的。

rjurney 回复 2月 前

@YaroslavNikitenko 具有 61GB/RAM 的 r4.2xlarge 是 0.532 美元/小时。你在做什么没有那么有价值的科学计算?听起来不寻常,如果不是不合理的话。

Yaroslav Nikitenko 回复 2月 前

@rjurney 抱歉,也许我应该删除我的评论。您对“不合理”的科学计算机的判断似乎非常主观。我多年来一直在笔记本电脑上进行科学计算,这对我来说似乎已经足够了,因为我大部分时间都在编写代码。从编程的角度来看,我的算法比从计算的角度来看要困难得多。此外,我很确定要编写可扩展的算法,不应依赖当前的硬件限制。您对他人计算的评论可能听起来有点冒犯(除了主观性),您介意删除这几个词吗?

thclark 回复 2月 前

对问题的主观和无益的非回答。这可能有一个经济论点,这取决于执行次数 x cpu 时间成本是否超过升级成本。这种方法只能通过硬件限制而不是数据大小来扩展。另外:在研究人员的笔记本电脑上取得了如此多的数据科学成就!另外,那些没有钱购买大型工作站的学者、学生和初创公司怎么办?!

rjurney 回复 2月 前

@thclark您可以根据需要优化到地狱并返回,但是使用大型计算机最容易完成具有大型数据集的科学计算……只要它适合RAM。如果不是你需要一个分布式系统,但他没有那个问题所以我没有给出那个答案。至于钱,你不需要把钱花在昂贵的工作站上。只需在需要时租一个小时即可。你会更快乐,更有效率!

0
chishaku 回答 2月 前

我知道这是一个旧线程,但我认为火焰图书馆值得一看。它专为这些类型的情况而设计。
从文档:
Blaze 将 NumPy 和 Pandas 的可用性扩展到分布式和核外计算。 Blaze 提供了一个类似于 NumPy ND-Array 或 Pandas DataFrame 的接口,但将这些熟悉的接口映射到各种其他计算引擎,如 Postgres 或 Spark。
编辑:顺便说一句,它得到了 ContinuumIO 和 NumPy 的作者 Travis Oliphant 的支持。

waterproof 回复 2月 前

另一个可能值得一看的库是 GraphLab Create:它具有高效的类似 DataFrame 的结构,不受内存容量的限制。blog.dato.com/…

0
brian_the_bungler 回答 2月 前

pymongo 就是这种情况。我还在 python 中使用 sql server、sqlite、HDF、ORM (SQLAlchemy) 进行了原型设计。首先,pymongo 是一个基于文档的数据库,因此每个人都是一个文档(dict属性)。许多人组成一个集合,您可以拥有多个集合(人、股票市场、收入)。
pd.dateframe -> pymongo 注意:我使用chunksizeread_csv将其保持在 5 到 10k 条记录(如果更大,pymongo 会丢弃套接字)

aCollection.insert((a[1].to_dict() for a in df.iterrows()))

查询:gt = 大于…

pd.DataFrame(list(mongoCollection.find({'anAttribute':{'$gt':2887000, '$lt':2889000}})))

.find()返回一个迭代器,所以我通常使用ichunked切成更小的迭代器。
加入一个怎么样,因为我通常会将 10 个数据源粘贴在一起:

aJoinDF = pandas.DataFrame(list(mongoCollection.find({'anAttribute':{'$in':Att_Keys}})))

然后(在我的情况下,有时我不得不继续aJoinDF首先在其“可合并”之前。)

df = pandas.merge(df, aJoinDF, on=aKey, how='left')

然后您可以通过下面的更新方法将新信息写入您的主集合。 (逻辑集合与物理数据源)。

collection.update({primarykey:foo},{key:change})

在较小的查找中,只需非规范化即可。例如,您在文档中有代码,您只需添加字段代码文本并执行dict在创建文档时查找。
现在你有一个很好的基于一个人的数据集,你可以在每个案例上释放你的逻辑并制作更多属性。最后,您可以将您的 3 to memory max 关键指标读入 pandas 并进行枢轴/聚合/数据探索。这对我来说适用于 300 万条带有数字/大文本/类别/代码/浮点数/…的记录
您还可以使用 MongoDB 中内置的两种方法(MapReduce 和聚合框架)。有关聚合框架的更多信息,请参见此处,因为它似乎比 MapReduce 更容易,并且对于快速聚合工作看起来很方便。请注意,我不需要定义我的字段或关系,我可以将项目添加到文档中。在快速变化的 numpy、pandas、python 工具集的当前状态下,MongoDB 帮助我开始工作:)

Zelazny7 回复 2月 前

嗨,我也在玩你的例子,在尝试插入数据库时​​遇到了这个错误:In [96]: test.insert((a[1].to_dict() for a in df.iterrows())) --------------- InvalidDocument: Cannot encode object: 0.有什么想法可能是错的吗?我的数据框由所有 int64 dtypes 组成,非常简单。

brian_the_bungler 回复 2月 前

是的,我对一个简单的范围 DF 做了同样的事情,而来自 numpy 的 int64 似乎打扰了 pymongo。我玩过的所有数据都是从 CSV 转换而来的(与人工通过 range() 相比),并且类型很长,因此没有问题。在 numpy 中,您可以转换,但我确实认为这有损。我必须承认 HDF 的 10.1 项目看起来令人兴奋。