V2EX = way to explore
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
yanyuechuixue
V2EX  ›  Python

求教, Python 如何把一个二维 list 存入文件,再读成原来的模样?

  •  
  •   yanyuechuixue · 2016-03-04 21:27:53 +08:00 · 11343 次点击
    这是一个创建于 3186 天前的主题,其中的信息可能已经有所发展或是发生改变。

    楼主不是专业程序员,请见谅。。。

    楼主在做科学计算,要把每个“类星体”的一些数据做一些计算,然后按照计算结果把这些类星体分类(分成 8 * 8 的 64 类),我想到的办法是建立了一个二维 list ( 8 * 8 )的,然后计算东西,计算完成后根据其结果把(类星体文件名,计算出的一个文件的属性)放到这个 list 里去。

    但由于数据太多,如果用单线程跑的话,可能要跑几个月,所以想把这个任务拆开,而我不会多进程(多线程倒是试过,但是只能 120%左右,提升不大),所以想把这个任务写成多个程序,分开跑,每个程序的这个二维 list 都存成一个文件,都跑完之后再把这个文件合起来。

    那么问题来了,我找了一天资料,依然不会把二维 list 存成文件。。。
    file.write()只能存放字符串,而我也没找到用 NumPy 创建空的二维数组的函数(虽然一定有)。

    所以来求助各位,多谢!

    31 条回复    2016-03-09 11:49:54 +08:00
    nightv2
        1
    nightv2  
       2016-03-04 21:33:33 +08:00 via Android
    你的二维 list 是啥样子的? list 每一个元素事一个 list 么?", ".jion 把一个 list 转换为用逗号隔开的字符串,这样就可以把二维 list 转换为一个大的字符串
    donghouhe
        2
    donghouhe  
       2016-03-04 21:36:51 +08:00
    用 pickle 这个库
    yanyuechuixue
        3
    yanyuechuixue  
    OP
       2016-03-04 21:38:00 +08:00
    @nightv2 嗯,每个 list 的元素都是一个 list ,在小的 list 里存放的是[str,str] 或(str,str)
    我试试去。
    eote
        4
    eote  
       2016-03-04 21:38:42 +08:00   ❤️ 1
    用 json 吧,比 pickle 更通用一些
    Strikeactor
        5
    Strikeactor  
       2016-03-04 21:39:35 +08:00   ❤️ 1
    转成 json
    Septembers
        6
    Septembers  
       2016-03-04 21:40:09 +08:00
    msg7086
        7
    msg7086  
       2016-03-04 22:14:25 +08:00   ❤️ 1
    你这个需求叫做序列化,具体可以搜索 Python 序列化。
    Aether
        8
    Aether  
       2016-03-04 22:34:17 +08:00
    存放的话推荐使用数据库, redis ,很简单的。
    neoblackcap
        9
    neoblackcap  
       2016-03-04 22:36:01 +08:00 via iPhone
    用 Numpy 请一定要用它自带的矩阵数据结构,不要 list 套 list
    yanyuechuixue
        10
    yanyuechuixue  
    OP
       2016-03-05 00:17:22 +08:00
    @eote
    @Strikeactor
    非常感谢!
    这正是我需要的。
    yanyuechuixue
        11
    yanyuechuixue  
    OP
       2016-03-05 00:17:48 +08:00
    @msg7086 谢谢!
    random2case
        12
    random2case  
       2016-03-05 00:18:47 +08:00
    冒昧问一下,如果写成二进制流的话,能不能合并在一起?
    yanyuechuixue
        13
    yanyuechuixue  
    OP
       2016-03-05 00:19:34 +08:00
    @Septembers 谢谢!
    20015jjw
        14
    20015jjw  
       2016-03-05 00:46:08 +08:00 via Android
    lz 自己徒手发明了 external algorithm
    lz 你看看 spark 嘛 这样就能分布化了 xd
    你要找的是 serializer
    seki
        15
    seki  
       2016-03-05 01:04:04 +08:00
    可能是我没理解对,就先按我理解的来说吧
    二维 list 用 numpy 的二维数列就可以
    如果你知道是 8*8 的,那直接 ones 或者 zeros 就好了
    然后 numpy 是可以存变量为文件的,读取也没问题, packle 其实也是一种方法

    multiprocessing 使用的时候对于函数的写法是需要一点技巧,可能需要掌握 functool
    LINAICAI
        16
    LINAICAI  
       2016-03-05 03:16:27 +08:00
    序列化和反序列化
    yangzh
        17
    yangzh  
       2016-03-05 05:19:08 +08:00 via iPhone
    kevinyoung
        18
    kevinyoung  
       2016-03-05 09:50:35 +08:00   ❤️ 1
    用 numpy ,话说数学计算怎么能离得开 numpy 呢

    import numpy as np
    two_d_list = [[1, 2], [3, 4]]
    numpy_list = np.asarray(two_d_list)
    print numpy_list.shape # 应该是(2, 2) ,也就是所谓的 2*2 的数组
    savetxt("./my_list.txt", numpy_list) # 这样就以文本的形式把刚才的数组保存下来了

    reloaded_list = loadtxt("./my_list.txt") # 又回来了

    我自己在做一些计算的时候数据一般是在循环体里循环一次出一个,所以先放进嵌套的 Python 的 list 里面,然后用 np.asarray()转化成 ndarray ,然后再做处理就非常简单了,存取只是其中一个方面,而且只要对齐,任何尺寸的都是可以的。
    staticor
        19
    staticor  
       2016-03-05 11:05:31 +08:00   ❤️ 1
    我还想说 pandas, 能用 numpy 就多看看 pandas. 数据民工的建议
    yanyuechuixue
        20
    yanyuechuixue  
    OP
       2016-03-05 11:39:44 +08:00
    @kevinyoung 谢谢!非常感谢!
    yanyuechuixue
        21
    yanyuechuixue  
    OP
       2016-03-05 11:40:12 +08:00
    @staticor 同数据民工,我看看去。
    imn1
        22
    imn1  
       2016-03-05 11:57:41 +08:00
    pandas
    yanyuechuixue
        23
    yanyuechuixue  
    OP
       2016-03-05 12:27:58 +08:00
    @20015jjw Spark 好复杂。。。。我不是专业干这个的。。。我是兼职。。。
    yuelang85
        24
    yuelang85  
       2016-03-05 14:00:25 +08:00
    具体每个元素的数据是什么样呢?

    我想说,你这样做的话,就不要用同一个文件,因为有的进程速度快,有的进程速度慢,存取的时候会有顺序问题,而且还有读写安全问题。

    我觉得最好的办法是开 64 个进程,存 64 个文件,然后组合成二维数组。

    关于写入文件什么内容。楼主可以像上面说的,看下 pickle , pickle 可以把 python 对象序列化成字符串,再反序列化成 python 对象
    yanyuechuixue
        25
    yanyuechuixue  
    OP
       2016-03-06 00:14:34 +08:00
    @kevinyoung 请问,我现在用您的方法,是成功的。
    但是我需要先创建一个空的,可以存放("str1",'str2')这样打数据的一个二位数组,该怎么创建?
    即创建一个空的数组,可以存放如下结构:
    [[('str1','str2'),('str5','str6')],[(str3',('str4'))],[]
    [],[],[]
    [],[],[]]

    我现在的做法是:

    Abins=[[[1] for x in range(5)] for y in range(5)]
    Abins=np.asarray(Abins,dtype=np.str)
    for i in range(2500):
    for i in range(2500):
    Abins[i][j]=[]
    但是并不好使,
    In [26]: Abins
    Out[26]:
    array([], shape=(50, 50, 0),
    dtype='|S1')
    yanyuechuixue
        26
    yanyuechuixue  
    OP
       2016-03-06 00:20:59 +08:00
    @seki 首先谢谢,我试了一下您提出的方法,对我来说不是太适用,是这样,我希望创建一个二维的 list ,例如是 8 × 8 的,这样就有 64 个元素,其中这 64 个元素每一个都是一个 list ,我往这 64 个 list 里 append 一个('str1','str2')。

    请问这个可以怎么操作?
    非常感谢!
    glogo
        27
    glogo  
       2016-03-06 01:28:50 +08:00
    序列化,用 pickle ,性能不够的话考虑 dill
    seki
        28
    seki  
       2016-03-06 02:30:49 +08:00
    @yanyuechuixue 如果你的长度是固定且相等的话,那么就是创建一个 3d array 然后往里面赋值。如果是变长的或者不等的,那就只能用 list

    pickle 在这种情况下是比较好的方法,不管是什么对象,全都塞进去就是了
    seki
        29
    seki  
       2016-03-06 02:40:24 +08:00
    @yanyuechuixue

    import numpy as np
    a = np.zeros((8,8,2), dtype=object)
    a[0,0,0] = 'hello'


    或者
    import numpy as np
    a = np.zeros((8,8), dtype=object)
    a[0,0] = ["hello","world"]
    kevinyoung
        30
    kevinyoung  
       2016-03-06 10:01:52 +08:00
    @yanyuechuixue 你的意思是你的数组是用来存放字符串的元组的是把?

    抱歉我一开始意会错了, numpy 虽然也可以处理字符串但并没有什么明显的优势, numpy 适合那种数据量比较大并且都是数字的情况。

    我又看了一下你这个问题,如果只是单纯的读写的话,直接用 python 的 list ,然后前面大家提到的用 pickle 或者 json 做序列化都是可以的。

    不过我觉得你可能把问题复杂化了,不如你把你要算的具体东西贴上来?不是代码,而是具体的问题,这样大家可以针对你的问题更具体的给一些建议。
    yanyuechuixue
        31
    yanyuechuixue  
    OP
       2016-03-09 11:49:54 +08:00 via Android
    @kevinyoung 嗯,我现在用的是 json 进行序列化。具体问题的话,就跟我在主题里说的一样。。。

    不是保密,理论物理的科学界不需要保密,只是我只能提取到这种程度了,再说多了也没几个人懂。。。因为再多就是很专业的知识了。。

    目前用 json ,算是解决了问题,非常感谢您!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1918 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:17 · PVG 00:17 · LAX 08:17 · JFK 11:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.