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

文档内容如下:

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

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

大家讲道理
大家讲道理

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

répondre à tous(4)
阿神

Si vous souhaitez conserver l'ordre de sortie, vous devez utiliser OrderedDict. La clé utilise OrderedDict pour maintenir l'ordre. Les informations suivantes utilisent list pour maintenir l'ordre. être gâché, utilisez set pour maintenir l'ordre Bon choix

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

Expliquez toutes les considérations pour ce code.


La première est la commande. La commande ici comporte deux parties, l'une est l'ordre des lignes de sortie et l'autre est l'ordre après la fusion des éléments. Nous avons observé :

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

devient :

pr333 sd23a2 thisisa|sentence 1001 1005
pr33w sd11aa we|have|adream 1022|1033 1002
  1. L'ordre des lignes de sortie est à prendre en compte : pr333 vient avant pr33w

  2. L'ordre après fusion des projets doit être pris en compte : thisisa vient avant la phrase

Cela signifie que le type de données que nous utilisons doit pouvoir maintenir la commande


La seconde est la rapidité. Nous savons tous que le type séquence est une recherche linéaire Pour plus d'efficacité, il est préférable d'utiliser le type mappage.

Après trois considérations, comme l'a dit moling3650, OrderedDict est un bon choix. Cela peut résoudre le problème de la sortie de ligne, mais comme le projet de fusion n'a besoin d'utiliser que la clé et non la valeur, il est dommage d'utiliser OrderedDict. Cependant, il n'y a actuellement aucune option OrderSet dans la bibliothèque standard, donc je dois me contenter.

  1. Pour plus d'informations sur OrderedDict, veuillez vous référer à OrderedDict

  2. En fait, il existe une bibliothèque tierce OrderedSet
    ou vous pouvez l'implémenter vous-même, veuillez vous référer à OrderedSet (recette Python)


Enfin, linkse7en a un très bon point. Pour ce genre de problème de traitement de documents, si vous savez lire et écrire en même temps, la lecture et le traitement en même temps seront certainement efficaces (car vous n'avez besoin de traiter le document qu'une seule visite)() et 討論請見評論部分 moling 大的觀點économiser des ressources (la sortie est terminée immédiatement, pas besoin de perdre de l'espace pour stocker les données). Cependant, étant donné que des paires de données en double peuvent apparaître sur les lignes , il est toujours nécessaire de dépenser plus de ressources pour assurer la stabilité.


Code (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])

J'expliquerai également la partie code (peut-être que mon écriture n'est pas la meilleure, mais je peux partager quelques expériences).

Le premier est l'application de

classe. slice

En tant que programmeur Python, nous devrions être familiers avec le

type de séquence le découpage.

items[start:stop:step]
peut en fait s'écrire ainsi :

items[slice(start, stop, step)]

# example
items[:5]  可以寫成  items[slice(0,5)]
items[7:]  可以寫成  items[slice(7,None)]
Quels sont les avantages ?

Nous pouvons utiliser cette fonctionnalité pour nommer des tranches. En prenant le code de cette question comme exemple, nous voulions à l'origine extraire la

paire de données et les autres données.

items = tuple(line.split())
items[0:2]  # 這是用來做 key 的數據對
items[2:]   # 這是其他的資料項
Mais cette méthode n'est en fait pas assez claire pour être lue. Nous pouvons donner un nom à ces deux plages, donc :

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

d'une manière plus élégante et plus lisible. items


La seconde est

, cette fonction est assez pratique, par exemple : setdefault

dic.setdefault(key, default_value)
Si la valeur clé

existe dans le dictionnaire (ou autre type de mappage correspondant), retournez key Sinon, le retour insérera automatiquement une nouvelle paire clé-valeur dic[key] dans le dictionnaire et renverra . dic[key] = default_value default_value

La dernière chose que je veux partager est le démontage des tuples imbriqués :
for (a, b), c, d in ((1,2) ,3, 4):
    print(a, b, c, d)  # 印出 1 2 3 4

Cette technique peut être facilement utilisée pour démanteler des tuples imbriqués.


Merci à tous de ne pas vous plaindre du fait que je parle trop...

刘奇

Est-il plus pratique d'utiliser des pandas ?

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

Quatre lignes résoudront le problème
J'ai d'abord enregistré le document sous le format example.txt

小葫芦
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
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal