文本处理(从两个文件读取和计算)

文本处理(从两个文件读取和计算)

我有如下一篇文本:(单词,单词域)

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

我知道它有点复杂,但我们将不胜感激。也许另一种方法更容易?

答案1

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

答案2

这确实相当复杂。我建议创建一个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。这似乎不是这里的问题,因为你的向量非常大。另外, kat的初始化-log(0)以获取它的inf值有点奇怪,但我不知道如何inf直接将其设置为(=inf显然不起作用)。你也许可以让它处理更多的情况(例如,如果你的向量中有几次相同的值......),但我会把它留给你,因为你现在有了一个起点!

答案3

TXR口齿不清与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

如果我们删除该(:inputs ...)子句,我们可以使用一对命令行参数提供文件:

$ txr munge.tl file1 file2

TXR Lisp 是一种类型安全的动态语言,其中变量必须在赋值或使用之前定义。不存在的变量和垃圾字符串不是数字零,也不是字符串类似的数字不是那些数字。这就是为什么我们显式定义哈希表的存在,并使用fconv显式将第二个及后续字段转换为实数(r)。

相关内容