Intereting Posts
Несколько аргументов в линиях shebang socat для совместного использования последовательного порта от linux to solaris Как написать домашнему пользователю с chrooted sftp Как я могу использовать экран для обучения и / или дистанционной помощи? Есть ли простая команда linux, которая сообщит мне, что мой диспетчер дисплея? Проблема с sed-подстановкой в ​​многословном регулярном выражении Как изменить ускорение мыши в X на постоянной основе? Xorg – игнорировать событие первого щелчка при возобновлении с экрана Blanking Как извлечь строки между двумя шаблонами в одном столбце? Разница между / и // Nginx Owncloud 4 производит «Нет указанного входного файла». Преобразование файлов .docx в обычный текст и сохранение разрывов строк для поддержания ссылок на номера строк на исходный документ: howto & implications? Почему Linux хранит температуры процессора в большом количестве файлов? Как grep для алфавитов, за которыми следует пробел и знак препинания? Как автоматически записывать все сеансы терминала с помощью утилиты сценария

текстовая обработка (чтение и вычисление из двух файлов)

У меня есть один текст: (слова, домены слов)

car transport car machine bank economy bank politics bank parks God religion ... 

Есть много слов, некоторые слова имеют разные домены, а у других есть только один домен. У меня есть еще один файл, огромная матрица (300 размерностей каждой строки), состоящая из слов и вектора для каждого типа:

 bank 0.9 1.5 3.2 -0.2 0.1 ... God 1.0 2.1 -0.5 0.7 ... rose 0.2 -1.8 ... ... ... 

Я хотел бы прочитать, сколько раз появляется каждое слово в первом файле и в соответствии с этим выбирают самые высокие «n» числа в каждом векторе второго файла, зная, к какому полю оно принадлежит. Что-то вроде этого:

 car 2 bank 3 God 1 

и передать эти числа в

 bank 4 3.2 bank 3 1.5 bank 2 0.9 God 3 2.1 

Первая часть, о которой я думал

 gawk 'NR==FNR {a[$1]++;next;} dont know what here?' list matrix 

Я знаю его немного сложнее, но любая помощь приветствуется. Может быть, другой способ проще?

 awk ' NR==FNR{ #operate matrix file first A[$1] = 1 #array of words for(i=2;i<=NF;i++) B[$1 OFS i] = $i #array with indexes [word field_num] next } $1 in A{ #if word in array A max = $1 OFS 2 for(i in B) if(i ~ "^" $1 && B[max] < B[i]) max = i #find maximum in B-array print max, B[max] #output word + field_num + value delete B[max] #exclude value from next search } } ' matrix list 

Если версия awk позволяет упростить скрипт псевдо-многомерных массивов

 awk ' NR==FNR{ for(i=2;i<=NF;i++) A[$1][i] = $i next } $1 in A{ max = 2 for(i in A[$1]) if(A[$1][max] < A[$1][i]) max = i print $1, max, A[$1][max] delete A[$1][max] } } ' matrix list 

Это действительно довольно сложно. Я бы предложил создать awk скрипт, если кто-то не придумает чудо-однострочный.

Внутри вашего файла awk :

 NR==FNR { a[$1]++ next } #Your probably know what that does since it's your starting point # If first field is a key in array a $1 in a { # Assign the number of occurences of this word in variable n n=a[$1] # Initialize this value to + INFINITY k=-log(0) # Loop on the number of occurences of the word for (i=0; i<n; i++) { # Initialize max value and its index at the first value of the vector m=$2 i_m=2 # Loop on the number of fields in the matrix for that word for (j=3; j<NF+1; j++) { # Look for the largest value that stays below previous max (if none then k is INFINITY) if ($j > m && $j < k) { m=$j; i_m=j } } # Print the word, the index of its max and its value printf $1" "i_m" "m"\n" # Store the max to be able to scan for the next biggest number at next iteration k=m } } 

Чтобы запустить его:

 $ awk -f myScript.awk list matrix 

Мой скрипт, похоже, работает нормально, за исключением одного случая: если в list есть равное число или больше вхождений слова, чем в его векторе в matrix есть значения. Это не похоже на проблему, так как ваши векторы довольно большие. И инициализация k at -log(0) чтобы получить ее значение inf , немного странно, но я не мог понять, как установить ее непосредственно в inf ( =inf не работает явно). Возможно, вы можете обработать больше случаев (если у вас есть одно и то же значение несколько раз в вашем векторе, например …), но я оставлю его вам, поскольку у вас есть начальная точка сейчас!

TXR Lisp с макросом awk :

 (let ((h (hash :equal-based))) (awk (:inputs "word-dom-pairs") (t (inc [h [f 0] 0]))) (awk (:inputs "word-vectors") (t (whenlet ((count [h [f 0]])) (fconv - : r) (let* ((n-fn-pairs (zip (rest f) (range 2))) (n-fn-sorted [sort n-fn-pairs > first])) (each ((p [n-fn-sorted 0..count])) (prn [f 0] (second p) (first p)))))))) 

Бег:

 $ txr munge.tl bank 4 3.2 bank 3 1.5 bank 2 0.9 God 3 2.1 

Данные:

 $ cat word-dom-pairs car transport car machine bank economy bank politics bank parks God religion $ cat word-vectors bank 0.9 1.5 3.2 -0.2 0.1 God 1.0 2.1 -0.5 0.7 rose 0.2 -1.8 

Ниже приведена версия программы, развернутая в одно выражение awk :

 (awk (:inputs "word-dom-pairs" "word-vectors") (:let (h (hash :equal-based))) ((= arg 1) (inc [h [f 0] 0])) ((= arg 2) (whenlet ((count [h [f 0]])) (fconv - : r) (let* ((n-fn-pairs (zip (rest f) (range 2))) (n-fn-sorted [sort n-fn-pairs > first])) (each ((p [n-fn-sorted 0..count])) (prn [f 0] (second p) (first p))))))) 

Два :inputs от ранее выделенных awk -s объединяются в один. Мы заменяем безусловные истинные шаблоны t селекторами, на основе которых обрабатывается ввод данных переменной arg . Функция let которая связывает переменную хеш-таблицы, складывается в макрос awk :let clause.

Если мы удалим предложение (:inputs ...) , мы можем предоставить файлы, используя пару аргументов командной строки:

 $ txr munge.tl file1 file2 

TXR Lisp – это безопасный тип, динамический язык, в котором переменные должны быть определены до назначения или использования. Необязательные переменные и нежелательные строки не являются числовым нулем, а строки, которые выглядят как числа, не являются числами. Вот почему мы явно определяем существование хэш-таблицы и используем fconv для явного преобразования второго и последующих полей в действительные числа ( r ).