cari

Rumah  >  Soal Jawab  >  teks badan

python:怎样合并文档中有重复部分的行?

文档内容如下:

   (数据对)              (信息)
-----------------  ------------------------
  1         2         3        4       5
-----------------  ------------------------
pr333    sd23a2    thisisa    1001    1005
pr333    sd23a2    sentence    1001    1005
pr33w    sd11aa    we    1022    1002
pr33w    sd11aa    have    1022    1002
pr33w    sd11aa    adream    1033    1002
......

第 1, 2 列作为一个 数据对

如果前两列相同,判断后面的是否相同,如果不同就连接起来,合并成一行

如同下面的效果:

pr333    sd23a2    thisisa|sentence    1001    1005
pr33w    sd11aa    we|have|adream    1022|1033    1002
....

小白,不懂怎么做,只能想到用字典,好像又行不通,求各位大神帮忙

大家讲道理大家讲道理2886 hari yang lalu1169

membalas semua(4)saya akan balas

  • 阿神

    阿神2017-04-17 17:52:17

    Jika anda ingin mengekalkan susunan output, anda perlu menggunakan OrderedDict kekunci menggunakan OrderedDict untuk mengekalkan pesanan kena kacau, guna list untuk maintain orderset

    import re
    from collections import OrderedDict
    
    datas = OrderedDict()
    
    with open('info.txt') as f:
        for line in f:
            if not line.strip().startswith('pr'):
                continue
            items = re.split(r'\s+', line.strip())
            key = ' '.join(items[:2])
            if key not in datas:
                datas[key] = [[item] for item in items[2:]]
            else:
                for item, data in zip(items[2:], datas[key]):
                    data.append(item)
    
    for key, value in datas.items():
        print(key, *map('|'.join, value))

    balas
    0
  • 阿神

    阿神2017-04-17 17:52:17

    Terangkan semua pertimbangan untuk kod ini.


    Yang pertama ialah pesanan Pesanan di sini mempunyai dua bahagian, satu ialah susunan baris keluaran, dan satu lagi ialah susunan selepas item digabungkan. Kami memerhati:

    pr333    sd23a2    thisisa    1001    1005
    pr333    sd23a2    sentence    1001    1005
    pr33w    sd11aa    we    1022    1002
    pr33w    sd11aa    have    1022    1002
    pr33w    sd11aa    adream    1033    1002

    berubah kepada:

    pr333 sd23a2 thisisa|sentence 1001 1005
    pr33w sd11aa we|have|adream 1022|1033 1002
    1. Susunan baris keluaran perlu diambil kira: pr333 datang sebelum pr33w

    2. Perintah selepas menggabungkan projek perlu diambil kira: thisisa didahulukan sebelum ayat

    Ini bermakna jenis data yang kami gunakan mestilah dapat mengekalkan susunan


    Yang kedua ialah kelajuan Kita semua tahu bahawa jenis urutan adalah carian linear Untuk kecekapan, lebih baik menggunakan jenis pemetaan.

    Selepas tiga pertimbangan, seperti yang dikatakan moling3650, OrderedDict ialah pilihan yang baik. Ini boleh menyelesaikan masalah output talian, tetapi oleh kerana projek gabungan hanya perlu menggunakan kunci dan bukan nilai, sayang untuk menggunakan OrderedDict Namun, pada masa ini tiada pilihan OrderSet dalam perpustakaan standard, jadi saya kena buat dengannya.

    1. Untuk maklumat tentang OrderedDict, sila rujuk OrderedDict

    2. Malah, terdapat perpustakaan pihak ketiga OrderedSet
      atau anda boleh melaksanakannya sendiri, sila rujuk OrderedSet (resipi Python)


    Akhir sekali, linkse7en mempunyai titik yang sangat baik untuk masalah pemprosesan dokumen seperti ini, jika anda boleh membaca dan menulis pada masa yang sama, membaca dan memproses pada masa yang sama pasti akan menjadi efisyen<🎜. > (kerana anda hanya perlu memproses dokumen sekali Lawati)() dan 討論請見評論部分 moling 大的觀點menjimatkan sumber (output selesai serta-merta, tidak perlu membazir ruang untuk menyimpan data). Walau bagaimanapun, memandangkan pasangan data pendua mungkin muncul merentas baris , anda masih perlu membelanjakan lebih banyak sumber untuk memastikan kestabilan.


    Kod (Python3):

    from collections import OrderedDict
    
    data = OrderedDict()
    
    DPAIR = slice(0,2)
    MSG = slice(2,None)
    
    with open('data.txt', 'r') as reader:
        for line in reader:
            line = line.strip()
            items = tuple(line.split())
    
            msgs = data.setdefault(items[DPAIR], [OrderedDict({}) for msg in items[MSG]])
            for idx, msg in enumerate(msgs):
                msg.setdefault(items[MSG][idx], None)
    
    for (dp1, dp2), msgs in data.items():
        print(dp1, dp2, *['|'.join(msg.keys()) for msg in msgs])


    Saya juga akan menerangkan bahagian kod (mungkin tulisan saya tidak terbaik, tetapi saya boleh berkongsi beberapa pengalaman).

    Pertama ialah penggunaan kelas

    . slice

    Sebagai pengaturcara Python, kita harus biasa dengan

    jenis jujukan penghirisan.

    items[start:stop:step]

    sebenarnya boleh ditulis sebagai:

    items[slice(start, stop, step)]
    
    # example
    items[:5]  可以寫成  items[slice(0,5)]
    items[7:]  可以寫成  items[slice(7,None)]

    Apakah faedahnya?

    Kami boleh menggunakan ciri ini untuk menamakan hirisan dengan mengambil kod dalam soalan ini sebagai contoh, kami pada asalnya ingin mengekstrak

    pasangan data dan data lain menggunakan:

    items = tuple(line.split())
    items[0:2]  # 這是用來做 key 的數據對
    items[2:]   # 這是其他的資料項

    Tetapi cara ini sebenarnya tidak cukup jelas untuk dibaca Kami boleh memberi nama kepada dua julat ini, jadi:

    DPAIR = slice(0,2)
    MSG = slice(2,None)
    items[DPAIR] # 這是用來做 key 的數據對
    items[MSG]   # 這是其他的資料項

    Kita boleh mendapatkan nilai daripada

    dengan cara yang lebih elegan dan mudah dibaca. items


    Yang kedua ialah

    , fungsi ini agak praktikal, contohnya: setdefault

    dic.setdefault(key, default_value)

    Jika nilai kunci

    wujud dalam kamus (atau jenis pemetaan lain yang sepadan), kembalikan key Jika tidak, pulangan akan secara automatik memasukkan pasangan nilai kunci baharu dic[key] dalam kamus dan kembalikan <🎜. >. dic[key] = default_value default_value

    Perkara terakhir yang saya ingin kongsikan ialah pembongkaran tupel bersarang:
    for (a, b), c, d in ((1,2) ,3, 4):
        print(a, b, c, d)  # 印出 1 2 3 4

    Teknik ini boleh digunakan dengan mudah untuk membongkar tuple bersarang.


    Terima kasih semua kerana tidak merungut bahawa saya terlalu banyak bercakap...

    balas
    0
  • 怪我咯

    怪我咯2017-04-17 17:52:17

    Adakah lebih senang menggunakan panda?

    import pandas as pd
    df = pd.read_csv('example.txt',sep=' ',header=None)
    df = df.astype(str) # 将数字转换为字符串
    grouped = df.groupby([0,1])
    result = grouped.agg(lambda x:'|'.join(x))

    Empat baris akan menyelesaikan masalah
    Saya menyimpan dokumen sebagai contoh.txt dahulu

    balas
    0
  • 高洛峰

    高洛峰2017-04-17 17:52:17

    from collections import defaultdict
    
    a = '''
    pr333 sd23a2 thisisa 1001 1005
    pr333 sd23a2 sentence 1001 1005
    pr33w sd11aa we 1022 1002
    pr33w sd11aa have 1022 1002
    pr33w sd11aa adream 1033 1002
    '''
    
    data = defaultdict(dict)
    keys = []
    
    for line in a.split('\n'):
        if not line:
            continue
        items = line.split()
        key = ' '.join(items[:2])
        keys.append(key)
        for i, item in enumerate(items[2:]):
            data[key][i] = data[key].get(i, []) + [item]
    for key in sorted(list(set(keys)), key=keys.index):
        value = data[key]
        print key,
        for i in sorted(value.keys()):
            vs = list(set(value[i]))
            vs.sort(key=value[i].index)
            print '|'.join(vs),
        print
    

    balas
    0
  • Batalbalas