在 python 中保存和处理内存中的大字典的有效方法

2023-11-25

正如我做了一些测试,一个包含 3000 万个项目的 int=>int (不同值)的 python 字典可以轻松地占用我的 mac 上 >2G 的内存。由于我只使用 int 到 int dict,有没有比使用 python dict 更好的解决方案?

我需要的一些要求是,

  1. 在保存数千万级别的 int 到 int 项时内存效率更高
  2. 基本的字典方法,例如按键获取值和迭代所有项目
  3. 易于序列化为字符串/二进制文件将是一个优点

更新, 4. 很容易通过给定的键获取子集,例如 d.fromkeys([...])

Thanks.


至少有两种可能性:

arrays

您可以尝试使用两个数组。一个用于键,一个用于值,以便索引(键)==索引(值)

2017-01-05 更新:在数组中使用 4 字节整数。

数组将使用更少的内存。在使用 clang 编译 python 的 64 位 FreeBSD 机器上,一个包含 3000 万个整数的数组使用大约 117 MiB。

这些是我使用的 python 命令:

Python 2.7.13 (default, Dec 28 2016, 20:51:25) 
[GCC 4.2.1 Compatible FreeBSD Clang 3.8.0 (tags/RELEASE_380/final 262564)] on freebsd11
Type "help", "copyright", "credits" or "license" for more information.
>>> from array import array
>>> a = array('i', xrange(30000000))
>>> a.itemsize
4

导入数组后,ps报告:

USER     PID %CPU %MEM   VSZ  RSS TT  STAT STARTED    TIME COMMAND
 rsmith 81023  0.0  0.2  35480   8100  0  I+   20:35     0:00.03 python (python2.7)

制作数组后:

USER     PID %CPU %MEM    VSZ    RSS TT  STAT STARTED    TIME COMMAND
rsmith 81023 29.0  3.1 168600 128776  0  S+   20:35     0:04.52 python (python2.7)

驻留集大小以 1 KiB 为单位报告,因此 (128776 - 8100)/1024 = 117 MiB

通过列表推导,您可以轻松获得键满足特定条件的索引列表。然后,您可以使用该列表中的索引来访问相应的值...

numpy

如果你有 numpy 可用,那么使用它会更快,有更多的功能,并且使用的 RAM 稍少:

Python 2.7.5 (default, Jun 10 2013, 19:54:11) 
[GCC 4.2.1 Compatible FreeBSD Clang 3.1 ((branches/release_31 156863))] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> a = np.arange(0, 30000000, dtype=np.int32)

From ps:启动 Python 后 6700 KiB,导入 numpy 后 17400 KiB,创建数组后 134824 KiB。大约为 114 MiB。

此外,numpy 支持记录数组;

Python 2.7.5 (default, Jun 10 2013, 19:54:11) 
[GCC 4.2.1 Compatible FreeBSD Clang 3.1 ((branches/release_31 156863))] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> a = np.zeros((10,), dtype=('i4,i4'))
>>> a
array([(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0),
       (0, 0), (0, 0)], 
      dtype=[('f0', '<i4'), ('f1', '<i4')])
>>> a.dtype.names
('f0', 'f1')
>>> a.dtype.names = ('key', 'value')
>>> a
array([(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0),
       (0, 0), (0, 0)], 
      dtype=[('key', '<i4'), ('value', '<i4')])
>>> a[3] = (12, 5429)
>>> a
array([(0, 0), (0, 0), (0, 0), (12, 5429), (0, 0), (0, 0), (0, 0), (0, 0),
       (0, 0), (0, 0)], 
      dtype=[('key', '<i4'), ('value', '<i4')])
>>> a[3]['key']
12

在这里您可以分别访问键和值;

>>> a['key']
array([ 0,  0,  0, 12,  0,  0,  0,  0,  0,  0], dtype=int32)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 python 中保存和处理内存中的大字典的有效方法 的相关文章

随机推荐

  • C# MySQL like查询不带参数

    我正在使用查询来查找特定字段中的关键字 当我输入 parameter 然后添加带有值的参数时 它不起作用 但是当我直接输入值时 它起作用 任何人都可以帮助我将值作为参数传递给我的请询问 下面是我的代码 这可以工作并检索标题中包含 我的 一词
  • 如何防止使用 JPA 保存子对象?

    我在学校和学生实体之间建立了 OneToMany 关系 我想要做的是 当我保存学校对象时 不要保存或更新学生对象 当然也不要删除它们 当我尝试保存如下所示的学校对象时 它也会更新我的学生对象 但我不希望它们被更新 而只是可连接 有什么办法吗
  • C# 拦截WebBrowser发出的请求

    是否可以拦截所有的请求WebBrowser控制 我想修改每个请求的请求URI 包括图像 脚本 样式表等的请求 有一个活动叫 导航2之前 在发出任何请求之前调用 您可以使用它来修改传出请求
  • 无形状映射中的子类型多态性

    我构建了以下内容 import shapeless import poly object Main def main args Array String object iterateOverHList extends List gt Ite
  • 在未找到匹配项的 OPTIONAL MATCH 之后创建

    我正在尝试编写一个查询 如果另一个关系已经存在 它将创建一些关系 START a node 1 b node 2 c node 3 OPTIONAL MATCH a r1 RELATIONSHIP optional1 OPTIONAL MA
  • 判断CGPoint是否在图像区域内

    我试图弄清楚 CGPoint 是否位于图像的形状内 该图像是一个简单的黑色形状 如下面所附的两个 我想创建一个方法来确定 CGPoint 是否位于该形状的黑色区域内 我认为这需要两件事 1 将图像变成可以用代码读取的东西 不确定这将使用哪种
  • Flask 中的大文件上传

    我正在尝试实现一个烧瓶应用程序来上传文件 该文件可能非常大 比如差不多2G大小 我已经完成了服务器端处理功能 如下所示 app route upload
  • Volley 服务器错误,网络响应为空

    每次我尝试在 Volley 中使用 POST 方法时 都会出现严重错误 我在 getCause 中得到 null 值 在 get Network Response toString 中得到一些默认值 如果我使用 GET 方法 效果很好 我从
  • PUT POST 具有幂等性 (REST)

    我不太明白 HTTP 动词是如何定义为幂等的 我读到的只是 GET 和 PUT 是幂等的 POST 不是幂等的 但是您可以使用 POST 创建一个不会更改任何内容 例如在数据库中 的 REST API 或者为 PUT 创建一个在每次调用时都
  • pandas 数据框,按值复制

    我注意到我的程序中存在一个错误 它发生的原因是因为 pandas 似乎是通过引用而不是通过值复制 pandas 数据框 我知道不可变对象总是通过引用传递 但 pandas 数据帧不是不可变的 所以我不明白为什么它通过引用传递 有人可以提供一
  • Inno Setup,[Run] 中的空格和双引号

    我正在尝试在 Windows 上安排任务 但不幸的是 它不起作用 任务已创建 但不正确 当我查看任务的参数时 它说 PROGRAM C Program ARGUMENTS Files x86 AppName executable exe 我
  • C++11 中的命名空间问题?

    有人可以解释一下以下内容吗 cat test cpp include
  • 使用 LinkMovementMethod 时可以禁用 TextView 中的滚动吗?

    我在 textView 中使用可点击范围来仅允许部分文本可点击 它工作正常 只是 textView 向下滚动 这是我不想要的 发生这种情况是因为我使用 LinkMovementMethod 在需要时滚动 有没有办法取消滚动 Spannabl
  • 使用 Javascript 播放 HTML5 视频 [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我该如何使用JavaScript播放 HTML5
  • 作为“本地系统”运行 Windows 服务有哪些安全风险?

    我编写了一个作为 本地系统 运行的 NET Windows 服务 最近我读到 作为本地系统运行可能会将系统凭据暴露给黑客 使他们能够接管系统 当我作为本地系统运行服务时 涉及哪些风险以及如何预防这些风险 服务运行为LocalSystem是系
  • kubernetes 部署-容器未启动-错误- InvalidImageName

    以下是 Kubernetes 部署 yaml 文件 container图片部分 image https registry ng bluemix net test service test branch 67 imagePullPolicy
  • PHP basename() 和 pathinfo() 与多字节 UTF-8 文件名

    我发现 PHP 函数 basename 以及 pathinfo 对于多字节 utf 8 名称有奇怪的行为 它们删除所有非拉丁字符 直到第一个拉丁字符或标点符号 但是 此后 后续的非拉丁字符将被保留 basename x returns x
  • 是否可以使用 MongoDB 作为嵌入式数据库?

    正如标题所示 我喜欢将 MongoDB 服务器嵌入到我自己的 C 应用程序中 我在文档中没有找到这种模式 我正在寻找类似 SQLite 或 Firebird 的嵌入式模式 MongoDB 也可以实现这一点吗 无需自己编程 目前还没有办法嵌入
  • 为什么 json_decode 对于空数组返回 null?

    为什么这会回显 NULL 在我看来 它将被解码为一个空数组 我明显缺少什么吗 这是因为array NULL 在这种情况下 它不检查对象类型 gettype null 返回 null 而 gettype array 返回数组 希望你能明白其中
  • 在 python 中保存和处理内存中的大字典的有效方法

    正如我做了一些测试 一个包含 3000 万个项目的 int gt int 不同值 的 python 字典可以轻松地占用我的 mac 上 gt 2G 的内存 由于我只使用 int 到 int dict 有没有比使用 python dict 更