python:怎样合并文档中有重复部分的行?
大家讲道理
大家讲道理 2017-04-17 17:50:17
0
4
1149

文档内容如下:

   (数据对)              (信息)
-----------------  ------------------------
  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
....

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

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

membalas semua(4)
阿神

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))
阿神

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...

刘奇

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

小葫芦
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
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan