推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
RicardoScofileld
V2EX  ›  Python

有一个很大的 json 文件,要如何才能将它读到内存中呢, 4 个多 G

  •  1
     
  •   RicardoScofileld · Jun 5, 2018 · 16803 views
    This topic created in 3076 days ago, the information mentioned may be changed or developed.

    尝试用 pickle.loads 读到内存,直接内存溢出了,试着用 pandas.read_json()读取,但是报错,Excepted object or value 黔驴技穷,不知道该咋弄了

    Supplement 1  ·  Jun 5, 2018
    可能我的描述出了点问题,该对象是用 pickle.dump 出去的,然后再 load 进来的时候,会内存溢出。。。。。
    60 replies  •  2018-06-14 17:14:36 +08:00
    opengps
    opengps
    Jun 5, 2018
    1
    要不你试试用工具把内存映射成硬盘,然后当作硬盘读写?
    不过貌似没有长期免费的内存映射硬盘工具
    purebluesong
    purebluesong
    Jun 5, 2018
    2
    怎么写的怎么读吧,python 的 loads 会在内存中占用成 10 倍磁盘空间的大小。
    不过如果 Expected object or value 的话应该这个文件本身就有问题了,说不定因为文件大小限制而被截断了
    Luckyray
    Luckyray
    Jun 5, 2018 via iPhone
    3
    这么大还用 json 不太合适吧……
    likuku
    likuku
    Jun 5, 2018
    4
    某些数据库已经支持 Json 数据类型了,先塞进去,Py 再去读 DB 呢?
    zynlp
    zynlp
    Jun 5, 2018 via iPhone❤️1
    5
    加内存,就是这么直接
    janxin
    janxin
    Jun 5, 2018
    6
    才 4 个 G 不会爆内存的吧...你内存不够了?
    ho121
    ho121
    Jun 5, 2018 via Android❤️1
    7
    自己写个 json 解释器,支持流式读取
    twor2
    twor2
    Jun 5, 2018 via iPhone
    8
    开一个临时的大内存云服务器
    lesteryu
    lesteryu
    Jun 5, 2018❤️1
    9
    pip install ijson
    Bramblex2
    Bramblex2
    Jun 5, 2018 via iPhone
    10
    你这 json 什么结构啊…如果层数深还是长度长?
    iwtbauh
    iwtbauh
    Jun 5, 2018 via Android❤️1
    12
    @opengps Linux 自带 mount -t tmpfs 了解一下,内存文件系统,比内存盘还要高效
    shilyx
    shilyx
    Jun 5, 2018
    13
    将你的需求映射为数据接口由 c++来处理,C++用 rapidjson 来读取

    rapidjson 如果还是不行,就用 c++写一个针对文件的、有限功能的 json 库

    如果自己搞不定,就外包
    iwtbauh
    iwtbauh
    Jun 5, 2018 via Android
    14
    使用 64 位处理器,64 位操作系统和 64 位 Python 尝试

    从理论上讲,64 位进程的虚拟内存可以高达 EB 级别( 32 位进程的虚拟内存通常只有 2GB 或 3GB,不可能超过 4GB )
    scriptB0y
    scriptB0y
    Jun 5, 2018
    15
    建议使用 less 这种文本阅读工具看一下内容,然后根据内容用代码一部分一部分的读然后切成小文件,应该是比较快的方法。
    lihongjie0209
    lihongjie0209
    Jun 5, 2018
    16
    为什么不先导入到数据库
    graysheeep
    graysheeep
    Jun 5, 2018
    17
    搞策略交易么
    est
    est
    Jun 5, 2018
    18
    #9 楼 @lesteryu 回复正解。迭代式解析 json 即可。内存绝对不会爆炸。
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    19
    @opengps 没接触过这种工具,推荐一个谢谢啦
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    20
    @purebluesong 你说为啥 load 的时候,会达到文件本身 10 倍的内存占用呢,是因为 Python 的数据类型导致的吗
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    21
    @Luckyray 哎,我老大写的代码,要我优化,他服务器 32 个 G 的内存,给我开了一个 8G 的,我跑代码特么的动不动就内存溢出。真的头大
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    22
    @zynlp 真粗暴,有没有什么免费的骚操作
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    23
    @janxin 文件大小虽然是 4 个 G,但是 load 的时候会造成很多倍的内存占用,也不知道为什么
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    24
    @ho121 大佬,可以来个示范代码或者链接吗,万分感激
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    25
    @twor2 公司 32G 的服务器,也会跑崩
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    26
    @lesteryu 查阅相关资料的时候看到这个库,我去了解一下
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    27
    @Bramblex2 字典,嵌套字典
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    28
    @lihongjie0209 这算一个临时的中间文件,所以没有保存数据库
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    29
    @iwtbauh Python 版本倒是 64 位的其他就不知道了
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    30
    @shilyx 小弟的水平看来只能 GG 了
    linuxchild
    linuxchild
    Jun 5, 2018
    31
    单机 spark 试试?
    USNaWen
    USNaWen
    Jun 5, 2018
    32
    rapidjson,用 SAX+流式。
    https://github.com/Tencent/rapidjson
    ipeony
    ipeony
    Jun 5, 2018
    33
    导 mongodb 里
    flyingghost
    flyingghost
    Jun 5, 2018❤️4
    34
    首先,先搞清楚你把数据加载到内存后打算干吗。
    这坨数据就是比你内存大,和格式无关。哪怕它是再精简不过的 bin 格式,哪怕我用 c,都无法解决 8G 内存读取 800G 数据的矛盾。
    唯一的出路,就是根据数据格式和需求确定解析和计算模式,部分解析,部分计算,分治然后汇总。

    建议的几种读取方式:
    1,SAX 了解一下,事件流驱动的 xml 解析思路,搬到 json 上毫无问题。
    2,切割原 json 文件,给它补上恰当的开始、关闭符来确保结构。
    3,自己实现解析器,最 low 的状态机实现起来很简单的。然后一边解析一边处理一边丢弃。
    4,如果 json 数据有某种特征,预处理一下。(比如结构体其实不复杂元素也不多,但里面有个字段的值超大,那么先文本处理 json,把这个字段抽取出来形成外部文件,json 内只留个文件名索引)其实很多超大数据集要么结构简单只是数据条数多,要么条数不多但单条比较大,很容易做针对性处理。
    yedashuai
    yedashuai
    Jun 5, 2018
    35
    这是使用 generator 的最佳场景呀,流式读取和解析~~~
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    36
    @flyingghost 这个本来是很多个文件处理后生成的一个字典,然后用 pickle dump 出去,生成一个临时中间文件,避免下次使用的时候还要经过计算生成,但是在 load 的时候,不知道为什么内存占用会成倍的增长。
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 5, 2018
    37
    @yedashuai 用 pickle 生成的文件,要如何流式读取解析呢
    henglinli
    henglinli
    Jun 5, 2018 via iPhone
    38
    这就是典型设计问题啊
    jyf
    jyf
    Jun 5, 2018
    39
    有流式解析的 不过这要看你的数据本身的结构 34 楼已经说得很清楚了
    RedFlag2233
    RedFlag2233
    Jun 5, 2018 via Android
    40
    with as 😯
    crist
    crist
    Jun 5, 2018
    41
    请装 16G 的内存,谢谢。
    focusheart
    focusheart
    Jun 5, 2018
    42
    嗯,看了补充内容,标题有歧义。
    标题的一般理解是有个 4G 多的 xxx.json 的纯文本文件。
    而实际上是一个 pickle dump 出来的对象文件比如 xxx.pkl 。
    显然用 pd.read_json() 是无法读取这个 xxx.pkl 的,也不用考虑流式之类的问题。

    这样几种方法解决:
    1. 如#41 所说,加内存,简单有效省事。
    2. 用 json 的话,重新用 json.dump() 搞一个纯文本的 xxx.json。纯文本怎么都好办。
    3. pickle 并不适合搞大对象的保存。换个库来做对象序列化,marsahl 好一些,但是要注意 python 版本。
    diggerdu
    diggerdu
    Jun 5, 2018
    43
    临时加个 swapfile
    aimiyooo
    aimiyooo
    Jun 5, 2018
    44
    4 个 G 数据,加载到内存可远远不止 4G
    exhades
    exhades
    Jun 6, 2018
    45
    加内存咯....不过全部加载到内存干什么.....
    qwertyegg
    qwertyegg
    Jun 6, 2018
    46
    NoSQL
    feiffy
    feiffy
    Jun 6, 2018
    47
    如果都是条数多,嵌套层数少,相同元素多,可以流式读取文件,generator 处理啊
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 6, 2018
    48
    @jyf 额 是我的描述出了点问题,pickle.dump 是异于 json.dump 的,是一个超大的字典,dump 出去有 4 个多 G,但是 load 的时候内存占用成倍的增长,直接溢出
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 6, 2018
    49
    @crist 文件达到将近 5 个 G 的时候,32G 内存服务器偶尔会崩。。。。
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 6, 2018
    50
    @focusheart 是啊,我原以为这两个库作用是相同的,查阅资料的时候才发现是有区别的,误导了大家了,尴尬
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 6, 2018
    51
    @diggerdu 谢谢,我去了解一下
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 6, 2018
    52
    @aimiyooo 是啊,pickle dump 出去只有 4 个 G,load 进来的时候却成倍的增长,是不是因为数据结构的原因呢
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 6, 2018
    53
    @exhades 是经过处理计算的一个字典,为了减少下次运算时间,所以打算用空间换取时间,dump 出一个中间临时文件,到时候直接 load 进来的
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 6, 2018
    54
    @qwertyegg 如果用 nosql,我想了一下,对于 redis,貌似只能用 hash 类型,但是这个字典里面有嵌套,要保存的话,还是需要序列化
    lfzyx
    lfzyx
    Jun 6, 2018
    55
    大多数应用程序都必须检索整个对象,然后仅过滤出所需数据以进行进一步分析。借助 S3 Select,应用程序可以将过滤和访问对象内部数据的繁重工作卸载到 Amazon S3 服务。

    https://aws.amazon.com/cn/about-aws/whats-new/2018/04/amazon-s3-select-is-now-generally-available/?nc1=f_ls
    ofooo
    ofooo
    Jun 6, 2018
    56
    你老大 32G 内存,你就和你老大说一下不就完了吗。需求不合理就提。
    liangeeks
    liangeeks
    Jun 6, 2018
    57
    这么大,知道数据结构的话慢慢读,不用一次性 load 啊
    RicardoScofileld
    RicardoScofileld
    OP
    Jun 6, 2018
    58
    @liangeeks pickle dump 出去的,怎么慢慢读呢
    cctv1005s927
    cctv1005s927
    Jun 6, 2018
    59
    自己搞一个数据结构存放文件吧,json 的文件是有深度的,有些时候不读取完毕很难读取到一个 object 的内容。
    beforeuwait
    beforeuwait
    Jun 14, 2018
    60
    用 生成器呀
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4777 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 84ms · UTC 08:17 · PVG 16:17 · LAX 00:17 · JFK 03:17
    ♥ Do have faith in what you're doing.