【问题标题】:How to group array of the same name using Python?如何使用 Python 对同名数组进行分组?
【发布时间】:2015-08-13 21:41:08
【问题描述】:

我在一个文本文件中有上千个数组类别,例如:

A1 类和 A2 类:(matlab 代码中的数组)

A1={[2,1,2]};
A1={[4,2,1,2,3]};
A2={[3,3,2,1]};
A2={[4,4,2,2]};
A2={[2,2,1,1,1]};

我想使用 Python 来帮助我读取文件并将它们分组:

A1=[{[2,1,2]} {[4,2,1,2,3]}];  
A2=[{[3,3,2,1]} {[4,4,2,2]} {[2,2,1,1,1]}];

【问题讨论】:

    标签: python arrays list file python-2.7


    【解决方案1】:

    使用 dict 进行分组,我认为您的意思是分组为字符串,因为它们不是来自 .mat matlab 文件的有效 python 容器:

    from collections import OrderedDict
    od = OrderedDict()
    with open("infile") as f:
        for line in f:
            name, data = line.split("=")
            od.setdefault(name,[]).append(data.rstrip(";\n"))
    
    from pprint import pprint as pp
    pp((od.values()))
    [['{[2,1,2]}', '{[4,2,1,2,3]}'],
    ['{[3,3,2,1]}', '{[4,4,2,2]}', '{[2,2,1,1,1]}']]
    

    要对文件中的数据进行分组,只需编写内容:

    with open("infile", "w") as f:
        for k, v in od.items():
            f.write("{}=[{}];\n".format(k, " ".join(v))))
    

    输出:

    A1=[{[2,1,2]} {[4,2,1,2,3]}];
    A2=[{[3,3,2,1]} {[4,4,2,2]} {[2,2,1,1,1]}];
    

    这实际上是您想要的输出,从每个子数组中删除分号,将元素分组并将分号添加到组的末尾,以保持数据在您的 matlab 文件中有效。

    collections.OrderedDict 将保留原始文件中的顺序,而使用普通 dict 将没有顺序。

    更新文件时更安全的方法是写入临时文件,然后使用 NamedTemporaryFileshutil.move 将原始文件替换为更新后的文件:

    from collections import OrderedDict
    
    od = OrderedDict()
    from tempfile import NamedTemporaryFile
    from shutil import move
    
    with open("infile") as f, NamedTemporaryFile(dir=".", delete=False) as temp:
        for line in f:
            name, data = line.split("=")
            od.setdefault(name, []).append(data.rstrip("\n;"))
        for k, v in od.items():
            temp.write("{}=[{}];\n".format(k, " ".join(v)))
    move(temp.name, "infile")
    

    如果代码在循环中出错或您的程序在写入过程中崩溃,您的原始文件将被保留。

    【讨论】:

    • 使用OrderedDict的任何特殊原因?
    • @SvenMarnach,它是一个文件,所以我认为顺序很重要,OP 所需的输出也是有序的。普通的字典会有相同的顺序吗?
    • 声称OrderedDict 将“保持原始文件的顺序”具有误导性。原始文件中的行可能按 A2、A2、A1、A2、A1、A1 的顺序排列。有序 dict 将以键 A2、A1 结尾,即每个键第一次出现的顺序。如果您假设这些行也按键分组,那么保持顺序可能是有意义的,但如果没有这个假设,我看不出它是如何有意义的。有了这个假设,我会使用itertools.groupby 寻求解决方案。
    • @SvenMarnach,我使用给定的输入并匹配所需的预期输出,我可以保证这样做的唯一方法是使用 OrderedDict。即使顺序是A2, A2, A1, A2, A1, A1.,您仍然保持第一次看到每个键的顺序,因此仍然有顺序,而不是使用普通字典没有任何顺序,我看不出这有什么误导性。是的,一旦元素被分组,groupby 也可以工作,但由于我没有完整的文件内容,所以我不能肯定地说。
    【解决方案2】:

    您可以先循环遍历行,然后使用= 拆分行,然后使用ast.literal_evalstr.strip 提取括号内的列表,最后使用带有setdefault 方法的字典来获得您的预期结果:

    import ast
    d={}
    with open('file_name') as f :
        for line in f:
            var,set_=line.split('=')
            d.setdefault(var,[]).append(ast.literal_eval(set_.strip("{}\n;")))
        print d
    

    结果:

    {'A1': [[2, 1, 2], [4, 2, 1, 2, 3]], 'A2': [[3, 3, 2, 1], [4, 4, 2, 2], [2, 2, 1, 1, 1]]}
    

    如果您希望结果完全符合您的预期格式,您可以这样做:

    d={}
    with open('ex.txt') as f,open('new','w')as out:
        for line in f:
            var,set_=line.split('=')
            d.setdefault(var,[]).append(set_.strip(";\n"))
        print d
        for i,j in d.items():
            out.write('{}=[{}];\n'.format(i,' '.join(j)))
    

    最后你会在新文件中得到以下结果:

    A1=[{[2,1,2]} {[4,2,1,2,3]}];
    A2=[{[3,3,2,1]} {[4,4,2,2]} {[2,2,1,1,1]}];
    

    【讨论】:

    • OP 在哪里对创建列表有任何说明?当一个简单的条带工作时,你也不需要翻译
    • @PadraicCunningham Op 没有说,但似乎他/她想要一个包含数组的数据结构。
    • 不,他们似乎想在文件中对行进行分组
    • @PadraicCunningham 是的,条带更直,这是一个建议,相对于 OP 的要求!
    • 该文件是一个 .mat 文件,它是 matlab 而不是 python,你看过想要的输出了吗?
    猜你喜欢
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多