查找 kdb+ 中单词对的数量

Find the count of word pairs in kdb+

我有一个包含多行项目代码的文件,如下所示。有 100 万行与这些类似

  1.  123,134,256,345,789.....
  2.  123,256,345,678,789......
   .
   .  

我想使用 kdb+ 中的 q 查找文件中每行所有 words/items 对的计数。即出现在同一行中的任何两对单词都可以被认为是一个单词对。 例如:

(123,134),(123,256),(134,256), (123,345) (123,789), (134,789) 是第 1 行中的一些单词对 (123,256),(123,345),(123,345),(678,789),(345,789)是第2行的一些词对

word/item pair count  

 `123,134----1 
  123,256---2
  345,789---2`

我正在使用 read0 读取文件,并且已经能够使用 vsusing count each group 将每一行转换为列表以计算字数,但现在我想找到文件中每行的所有单词对。

提前感谢您的帮助

我不是 100% 理解您对词对的定义。如果我的逻辑不符合您的要求,也许您可​​以稍微扩展一下。

在下面的示例中,我创建了一个用于测试的 5x5 符号矩阵 - 从每一行中选择不同的值对,然后检查每对值总共出现了多少行。

请仔细检查您自己的结果。

q)test:5 cut`$string 25?5

q)test
2 0 1 0 0
2 4 4 2 0
1 0 0 3 4
2 1 1 4 4
3 0 3 4 0

q)count each group raze {l[where(count'[l:distinct distinct each asc'[x cross x:distinct x]])>1]} each test
0 2| 2
1 2| 2
0 1| 2
2 4| 2
0 4| 3
1 3| 1
1 4| 2
0 3| 2
3 4| 2

要在上面 Matthew 的回答中添加一些其他案例,如果您想要以这种方式将列表分解成对:

l:"a,b,c,d,e,f,g"

变成

"a,b"
"b,c"
"c,d"
"d,e"
"e,f"
"f,g"

所以只取有效的对,你可以使用这样的东西:

f:{count each group b flip 0 1+\:til 1+count[b:","vs x]-1}

q)f l
,"a" ,"b"| 1
,"b" ,"c"| 1
,"c" ,"d"| 1
,"d" ,"e"| 1
,"e" ,"f"| 1
,"f" ,"g"| 1

我们在“.”上拆分输入列表,然后使用索引获取每个元素的列表和直接位于其右侧的元素,然后对结果对列表进行分组以计算不同的对。如果你想拆分它所以 l 变成

"a,b"
"c,d"
"e,f"  

那么你可以使用这个:

g:{count each group b flip 0 1+\:2*til count[b:","vs x]div 2}

q)g l
,"a" ,"b"| 1
,"c" ,"d"| 1
,"e" ,"f"| 1

它使用了类似的方法,从偶数位置的元素开始,将它们移到它们的右边,然后重复上述步骤。 您可以轻松地将这些应用到使用 read0:

读取的行
r:read0`:file.txt
f each r

将输出每行每对计数的字典,这可以求和以给出整个文件中每种方法的每个词对的总计数。

希望这有帮助 - 仍然不清楚你所说的成对是什么意思,所以如果我的回答和马修的回答都没有用,你可以编辑更完整的解释你想要什么,我们可以帮助那。

如果您想考虑每行中 2 对的所有可能组合,那么这可能会有所帮助。以下函数可用于给出不同的组合,其中 x 是列表的大小,y 是组合的长度:

q)comb:{$[x=y;enlist til x;1=y;flip enlist til x;.z.s[x;y],.z.s[x;y-1],'x-:1]}
q)comb[3;2]
0 1
0 2
1 2

从这里我们可以索引到每个列表以获取对,然后 raze 给出所有对的单个列表,group 获取每个对出现的索引,然后 count每组索引个数:

q)a
123 134 256 345 789
123 256 345 678 789
q)count each group raze{x comb[count x;2]}'[a]
123 134| 1
123 256| 2
134 256| 1
...
345 789| 2
...