【问题标题】:Shuffling text from file by group of data按数据组对文件中的文本进行洗牌
【发布时间】:2018-01-21 01:42:37
【问题描述】:

我一直在寻找 Python / Unix 命令中的一些方法,通过基于第一个单词值的分组来打乱大型文本数据集,如下所示-

输入文本:

"ABC", 21, 15, 45
"DEF", 35, 3, 35
"DEF", 124, 33, 5
"QQQ" , 43, 54, 35
"XZZ", 43, 35 , 32
"XZZ", 45 , 35, 32

所以它会被随机洗牌,但像下面这样保持组在一起

输出样本-

"QQQ" , 43, 54, 35  
"XZZ", 43, 35 , 32
"XZZ", 45 , 35, 32
"ABC", 21, 15, 45
"DEF", 35, 3, 35
"DEF", 124, 33, 5

我通过正常的改组找到了解决方案,但我不知道在改组时保留组。

【问题讨论】:

    标签: python shell unix random shuffle


    【解决方案1】:

    使用collections.defaultdict 可以做到这一点。通过按第一个序列识别每一行,您可以轻松地对它们进行排序,然后仅对字典的键进行采样,如下所示:

    import random
    from collections import defaultdict
    
    # Read all the lines from the file
    lines = defaultdict(list)
    with open("/path/to/file", "r") as in_file:
        for line in in_file:
            s_line = line.split(",")
            lines[s_line[0]].append(line)
    
    # Randomize the order
    rnd_keys = random.sample(lines.keys(), len(lines))
    
    # Write back to the file?
    with open("/path/to/file", "w") as out_file:
        for k in rnd_keys:
            for line in lines[k]:
                out_file.write(line)
    

    希望这对您的努力有所帮助。

    【讨论】:

    • 这个仍然只是随机顺序洗牌。我仍然无法对行的第一个字符串进行“分组”
    • 对不起,我没有理解你所说的“分组”的意思。
    • 对不起,如果我未能解释。正如我提到的“基于第一个单词的分组”,正如您在示例输出中看到的那样,以“XZZ”和“DEF”开头的行完全一致。这就是我所说的按第一个值分组的意思。行将是完整的,但以该行开头的类似单词也将被“分组”
    • 我编辑了我的答案以匹配您对分组的定义。再次为第一次没有正确阅读而道歉。
    • 像魅力一样工作!谢谢,也因为速度快;D
    【解决方案2】:

    您还可以将文件中的每一行存储到嵌套列表中:

    lines = []
    with open('input_text.txt') as in_file:
        for line in in_file.readlines():
            line = [x.strip() for x in line.strip().split(',')]
            lines.append(line)
    

    这给出了:

    [['"ABC"', '21', '15', '45'], ['"DEF"', '35', '3', '35'], ['"DEF"', '124', '33', '5'], ['"QQQ"', '43', '54', '35'], ['"XZZ"', '43', '35', '32'], ['"XZZ"', '45', '35', '32']]
    

    然后您可以将这些列表按第一项与itertools.groupby() 分组:

    import itertools
    from operator import itemgetter
    
    grouped = [list(g) for _, g in itertools.groupby(lines, key = itemgetter(0))]
    

    其中列出了您的分组项目:

    [[['"ABC"', '21', '15', '45']], [['"DEF"', '35', '3', '35'], ['"DEF"', '124', '33', '5']], [['"QQQ"', '43', '54', '35']], [['"XZZ"', '43', '35', '32'], ['"XZZ"', '45', '35', '32']]]
    

    然后你可以用random.shuffle() 随机播放这个:

    import random
    
    random.shuffle(grouped)
    

    这会给出完整的分组项目的随机列表:

    [[['"QQQ"', '43', '54', '35']], [['"ABC"', '21', '15', '45']], [['"XZZ"', '43', '35', '32'], ['"XZZ"', '45', '35', '32']], [['"DEF"', '35', '3', '35'], ['"DEF"', '124', '33', '5']]]
    

    现在您所要做的就是将最终列表展平并将其写入一个新文件,您可以使用itertools.chain.from_iterable()

    with open('output_text.txt', 'w') as out_file:
        for line in itertools.chain.from_iterable(grouped):
            out_file.write(', '.join(line) + '\n')
    
    print(open('output_text.txt').read())
    

    哪个 a 给出了您文件的新洗牌版本:

    "QQQ", 43, 54, 35
    "ABC", 21, 15, 45
    "XZZ", 43, 35, 32
    "XZZ", 45, 35, 32
    "DEF", 35, 3, 35
    "DEF", 124, 33, 5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 2017-02-09
      • 1970-01-01
      • 1970-01-01
      • 2017-11-28
      相关资源
      最近更新 更多