有一个很大的 json 文件,要如何才能将它读到内存中呢, 4 个多 G - V2EX
推荐学习书目
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

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

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

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

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

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

    建议的几种读取方式:
    1,SAX 了解一下,事件流驱动的 xml 解析思路,搬到 json 上毫无问题。
    2,切割原 json 文件,给它补上恰当的开始、关闭符来确保结构。
    3,自己实现解析器,最 low 的状态机实现起来很简单的。然后一边解析一边处理一边丢弃。
    4,如果 json 数据有某种特征,预处理一下。(比如结构体其实不复杂元素也不多,但里面有个字段的值超大,那么先文本处理 json,把这个字段抽取出来形成外部文件,json 内只留个文件名索引)其实很多超大数据集要么结构简单只是数据条数多,要么条数不多但单条比较大,很容易做针对性处理。
    yedashuai
        35
    yedashuai  
       Jun 5, 2018
    这是使用 generator 的最佳场景呀,流式读取和解析~~~
    RicardoScofileld
        36
    RicardoScofileld  
    OP
       Jun 5, 2018
    @flyingghost 这个本来是很多个文件处理后生成的一个字典,然后用 pickle dump 出去,生成一个临时中间文件,避免下次使用的时候还要经过计算生成,但是在 load 的时候,不知道为什么内存占用会成倍的增长。
    RicardoScofileld
        37
    RicardoScofileld  
    OP
       Jun 5, 2018
    @yedashuai 用 pickle 生成的文件,要如何流式读取解析呢
    henglinli
        38
    henglinli  
       Jun 5, 2018 via iPhone
    这就是典型设计问题啊
    jyf
        39
    jyf  
       Jun 5, 2018
    有流式解析的 不过这要看你的数据本身的结构 34 楼已经说得很清楚了
    RedFlag2233
        40
    RedFlag2233  
       Jun 5, 2018 via Android
    with as
    crist
        41
    crist  
       Jun 5, 2018
    请装 16G 的内存,谢谢。
    focusheart
        42
    focusheart  
       Jun 5, 2018
    嗯,看了补充内容,标题有歧义。
    标题的一般理解是有个 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
        43
    diggerdu  
       Jun 5, 2018
    临时加个 swapfile
    aimiyooo
        44
    aimiyooo  
       Jun 5, 2018
    4 个 G 数据,加载到内存可远远不止 4G
    exhades
        45
    exhades  
       Jun 6, 2018
    加内存咯....不过全部加载到内存干什么.....
    qwertyegg
        46
    qwertyegg  
       Jun 6, 2018
    NoSQL
    feiffy
        47
    feiffy  
       Jun 6, 2018
    如果都是条数多,嵌套层数少,相同元素多,可以流式读取文件,generator 处理啊
    RicardoScofileld
        48
    RicardoScofileld  
    OP
       Jun 6, 2018
    @jyf 额 是我的描述出了点问题,pickle.dump 是异于 json.dump 的,是一个超大的字典,dump 出去有 4 个多 G,但是 load 的时候内存占用成倍的增长,直接溢出
    RicardoScofileld
        49
    RicardoScofileld  
    OP
       Jun 6, 2018
    @crist 文件达到将近 5 个 G 的时候,32G 内存服务器偶尔会崩。。。。
    RicardoScofileld
        50
    RicardoScofileld  
    OP
       Jun 6, 2018
    @focusheart 是啊,我原以为这两个库作用是相同的,查阅资料的时候才发现是有区别的,误导了大家了,尴尬
    RicardoScofileld
        51
    RicardoScofileld  
    OP
       Jun 6, 2018
    @diggerdu 谢谢,我去了解一下
    RicardoScofileld
        52
    RicardoScofileld  
    OP
       Jun 6, 2018
    @aimiyooo 是啊,pickle dump 出去只有 4 个 G,load 进来的时候却成倍的增长,是不是因为数据结构的原因呢
    RicardoScofileld
        53
    RicardoScofileld  
    OP
       Jun 6, 2018
    @exhades 是经过处理计算的一个字典,为了减少下次运算时间,所以打算用空间换取时间,dump 出一个中间临时文件,到时候直接 load 进来的
    RicardoScofileld
        54
    RicardoScofileld  
    OP
       Jun 6, 2018
    @qwertyegg 如果用 nosql,我想了一下,对于 redis,貌似只能用 hash 类型,但是这个字典里面有嵌套,要保存的话,还是需要序列化
    lfzyx
        55
    lfzyx  
       Jun 6, 2018
    大多数应用程序都必须检索整个对象,然后仅过滤出所需数据以进行进一步分析。借助 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
        56
    ofooo  
       Jun 6, 2018
    你老大 32G 内存,你就和你老大说一下不就完了吗。需求不合理就提。
    liangeeks
        57
    liangeeks  
       Jun 6, 2018
    这么大,知道数据结构的话慢慢读,不用一次性 load 啊
    RicardoScofileld
        58
    RicardoScofileld  
    OP
       Jun 6, 2018
    @liangeeks pickle dump 出去的,怎么慢慢读呢
    cctv1005s927
        59
    cctv1005s927  
       Jun 6, 2018
    自己搞一个数据结构存放文件吧,json 的文件是有深度的,有些时候不读取完毕很难读取到一个 object 的内容。
    beforeuwait
        60
    beforeuwait  
       Jun 14, 2018
    用 生成器呀
    About     Help     Advertise     Blog     API     FAQ     Solana     1646 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 111ms UTC 16:31 PVG 00:31 LAX 9:31 JFK 12:31
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86