Эффективный метод для объединения 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)))