查找 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 读取文件,并且已经能够使用 vs
和 using 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
...
我有一个包含多行项目代码的文件,如下所示。有 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 读取文件,并且已经能够使用 vs
和 using 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
...