Эффективный метод для объединения 2 отсортированных файлов с дубликатами координат в Python

Я относительно новичок в Python и пытаюсь использовать его для объединения двух отсортированных файлов, которые содержат 4 столбца:

файл 1:

x-coordinate, y-coordinate, data 1, data 2  
1, 10, 20, 0  
5, 15, 1, 2  
...

файл 2:

x-coordinate, y-coordinate, data 3, data 4  
1, 10, 7, 8  
3, 25, 1, 2  
...

в один отсортированный файл с 6 столбцами, которые содержат каждый уникальный набор (x,y) координат:

x-coordinate, y-coordinate, data 1, data 2, data 3, data 4  
1, 10, 20, 0, 7, 8  
3, 25, 0, 0, 1, 2  
5, 15, 1, 2, 0, 0  

Я думаю, что эта задача была бы тривиальной с использованием словарей, если бы только порядок выходного файла не имел значения. Поскольку мои входные файлы имеют длину 100 с, я пытаюсь найти эффективный "питонический" способ обработки дублирующих случаев (т. Е. Когда одинаковые (x,y) координаты присутствуют в обоих файлах), но пока Я в тупике.

Любая помощь приветствуется. Заранее спасибо!

2 ответа

Решение

Используя панд:

import pandas as pd

df1 = pd.read_csv("coord1.csv")
df2 = pd.read_csv("coord2.csv")
combined = df1.merge(df2, how='outer').fillna(0)
combined.sort(list(combined.columns[:2]), inplace=True)
combined.to_csv("coord_merged.csv",index=False)

Сначала прочитайте в исходных данных:

>>> import pandas as pd
>>> df1 = pd.read_csv("coord1.csv")
>>> df2 = pd.read_csv("coord2.csv")
>>> df1
   x-coordinate   y-coordinate   data 1   data 2
0             1             10       20        0
1             5             15        1        2
>>> df2
   x-coordinate   y-coordinate   data 3   data 4  
0             1             10        7          8
1             3             25        1          2

Объедините их и заполните недостающие данные нулями:

>>> combined = df1.merge(df2, how='outer')
>>> combined
   x-coordinate   y-coordinate   data 1   data 2   data 3   data 4  
0             1             10       20        0        7          8
1             5             15        1        2      NaN        NaN
2             3             25      NaN      NaN        1          2
>>> combined = df1.merge(df2, how='outer').fillna(0)
>>> combined
   x-coordinate   y-coordinate   data 1   data 2   data 3   data 4  
0             1             10       20        0        7          8
1             5             15        1        2        0          0
2             3             25        0        0        1          2

Сортировать:

>>> combined.sort(list(combined.columns[:2]), inplace=True)
>>> combined
   x-coordinate   y-coordinate   data 1   data 2   data 3   data 4  
0             1             10       20        0        7          8
2             3             25        0        0        1          2
1             5             15        1        2        0          0

И напоследок выпиши:

>>> combined.to_csv("coord_merged.csv",index=False)
>>> !cat coord_merged.csv
x-coordinate, y-coordinate, data 1, data 2, data 3, data 4  
1.0,10.0,20.0,0.0,7.0,8.0
3.0,25.0,0.0,0.0,1.0,2.0
5.0,15.0,1.0,2.0,0.0,0.0

Если важно сохранить целочисленный формат, то

>>> combined.astype(int).to_csv("coord_merged.csv",index=False)
>>> !cat coord_merged.csv
x-coordinate, y-coordinate, data 1, data 2, data 3, data 4  
1,10,20,0,7,8
3,25,0,0,1,2
5,15,1,2,0,0

сделал бы это.

Я бы, наверное, использовал defaultdict для чего-то вроде этого:

from collections import defaultdict
from itertools import chain   

d = defaultdict(lambda:[0,0,0,0])
with open('file1') as f1, open('file2') as f2:
    next(f1) #get rid of header info
    next(f2)
    for line1,line2 in zip(f1,f2):
        data1 = [int(x) for x in line1.split(',')]
        data2 = [int(x) for x in line2.split(',')]
        d[tuple(data1[:2])][:2] = data1[2:]
        d[tuple(data2[:2])][2:] = data2[2:]

#now sort the items and write them out:
#This puts them in stdout, but you could easily use `file.write` here.
for k,v in sorted(d.items()):
    print(', '.join(str(x) for x in chain(k,v)))
Другие вопросы по тегам