Присоединение к двум текстовым файлам с несколькими ключами

У меня есть два набора данных. и я хочу присоединиться к ним двумя значениями ключа (storm_ID, Cell_ID).

Первый набор данных похож:

Storm_ID,Cell_ID,Wind_speed 
2,10236258,27 
2,10236300,58 
2,10236301,25 
3,10240400,51

Второй набор данных похож:

Storm_ID,Cell_ID,Storm_surge 
2,10236299,0.27 
2,10236300,0.27 
2,10236301,0.35 
2,10240400,0.35 
2,10240401,0.81 
4,10240402,0.11

Теперь я хочу вывод, который выглядит примерно так:

Storm_ID,Cell_ID,Wind_speed,Storm_surge 
2,10236258,27,0 
2,10236299,0,0.27 
2,10236300,58,0.27 
2,10236301,25,0.35 
2,10240400,0,0.35 
2,10240401,0,0.81 
3,10240400,51,0 
4,10240402,0,0.11

Я попробовал, присоединяются к команде в Linux для выполнения этой задачи и отказавший плохо. Команда соединения пропустила строки, которые не соответствовали в базе данных. Я могу использовать Matlab, но размер данных составляет больше чем 100 ГБ, который делает это очень трудным для этой задачи. Может кто-то вести меня на этом. Я могу использовать SQL или Python для выполнения этой задачи.

2
задан 30 March 2018 в 08:20

2 ответа

Вы можете, делают это с join если Вы объедините первые два поля в единственный ключ путем замены разделителя запятой символом, что можно быть уверены, не появится в данных. Обратите внимание на это с тех пор join требования, чтобы данные были отсортированы на объединяющем поле, это будет только работать, если выполнение так не изменяет лексический порядок данных.

Например:

$ join -t, -a1 -a2 -e0 -o0,1.2,2.2 <(sed 's/,/;/' file1) <(sed 's/,/;/' file2) | sed 's/;/,/'
Storm_ID,Cell_ID,Wind_speed,Storm_surge
2,10236258,27,0
2,10236299,0,0.27
2,10236300,58,0.27
2,10236301,25,0.35
2,10240400,0,0.35
2,10240401,0,0.81
3,10240400,51,0
4,10240402,0,0.11
4
ответ дан 2 December 2019 в 01:29

Используя awk и вид:

awk -F, -v OFS=, '{x = $1 "," $2} FNR == NR {a[x] = $3; b[x] = 0; next} {b[x] = $3} !a[x] {a[x] = 0} END {for (i in a) print i, a[i], b[i]}' f1 f2 | sort -n
  • -F, -v OFS=, - установите ввод и вывод, который будет разделен ,
  • {x = $1 "," $2} сохраните первые два поля, разделенные ,, так как комбинация быть общим индексом.
  • FNR == NR {a[x] = $3; b[x] = 0; next} - FNR рекордное число на файл, и NR полное рекордное число через файлы. Они равны для первого файла, таким образом, этот блок выполняется только для первого файла. Здесь, я сохраняю третий столбец первый файл в массиве a, и инициализируйте соответствующую запись в b к 0. И затем я пропускаю к следующей записи.
  • {b[x] = $3} !a[x] {a[x] = 0} - эти два выполняются для второго файла, сохраняя третий столбец в b, и если нет никакой соответствующей записи в a, установите его на 0.
  • END {for (i in a) print i, a[i], b[i]}, в конце обоих файлов распечатайте каждую запись, полученную до сих пор

Так как цикличное выполнение по массивам в awk дает произвольное распоряжение, мы должны отсортировать вывод в конце с sort -n:

$ awk -F, -v OFS=, '{x = $1 "," $2} FNR == NR {a[x] = $3; b[x] = 0; next} {b[x] = $3} !a[x] {a[x] = 0} END {for (i in a) print i, a[i], b[i]}' f1 f2 | sort -n
Storm_ID,Cell_ID,Wind_speed,Storm_surge
2,10236258,27,0
2,10236299,0,0.27
2,10236300,58,0.27
2,10236301,25,0.35
2,10240400,0,0.35
2,10240401,0,0.81
3,10240400,51,0
4,10240402,0,0.11
5
ответ дан 2 December 2019 в 01:29

Другие вопросы по тегам:

Похожие вопросы: