【发布时间】:2017-12-05 21:09:22
【问题描述】:
我需要帮助来加快计算重复数字比例的函数(忽略任何非数字)。该功能有助于在运行任何校验位验证之前识别用户的虚假条目(如果有的话)。想想假电话号码、假学生号码、假支票帐号、假信用卡号码、假任何标识符等等。
函数是this post的泛化。
这就是它的作用。对于指定数量的最频繁出现的数字,它计算字符串中最高数字与所有数字的比例,忽略所有非数字。如果字符串中没有数字,则返回 1.0。所有的计算都是在一个字符串向量上完成的。
library(microbenchmark)
V = c('(12) 1221-12121,one-twoooooooooo', 'twos:22-222222222', '34-11111111, ext.123',
'01012', '123-456-789 valid', 'no digits', '', NaN, NA)
Fake_Similarity = function(V, TopNDigits) {
vapply(V, function(v) {
freq = sort(tabulate(as.integer(charToRaw(v)))[48:57], decreasing = T);
ratio = sum(freq[1:TopNDigits], na.rm = T) / sum(freq, na.rm = T)
if (is.nan(ratio)) ratio = 1
ratio
},
double(1))
}
t(rbind(Top1Digit = Fake_Similarity(v, 1), Top2Digits = Fake_Similarity(v, 2), Top3Digits = Fake_Similarity(v, 3)))
microbenchmark(Fake_Similarity(v, 2))
与输出。标签不重要,但顺序比必须与对应字符串的原始顺序一致。
Top1Digit Top2Digits Top3Digits
(12) 1221-12121,one-twoooooooooo 0.5454545 1.0000000 1.0000000
twos:22-222222222 1.0000000 1.0000000 1.0000000
34-11111111, ext.123 0.6923077 0.8461538 0.9230769
01012 0.4000000 0.8000000 1.0000000
123-456-789 valid 0.1111111 0.2222222 0.3333333
no digits 1.0000000 1.0000000 1.0000000
1.0000000 1.0000000 1.0000000
NaN 1.0000000 1.0000000 1.0000000
<NA> 1.0000000 1.0000000 1.0000000
Unit: milliseconds
expr min lq mean median uq max neval
Fake_Similarity(v, 2) 1.225418 1.283113 1.305139 1.292755 1.304262 1.769703 100
例如,twos:22-222222222 有 11 位数字,所有数字都相同。因此,对于Top1Digit,我们有 11/11=1,对于Top2Digits,我们有 (11+0)/11=1,依此类推。换句话说,无论如何,这都是一个假数字。比方说,一个人的电话号码极不可能有相同的数字,包括区号。
【问题讨论】:
-
没有数字的时候不应该是0吗?
-
twos:22-222222222不应该是 0.647 吗? -
这个想法是过滤我们所有的虚假和无效数字(忽略所有非数字)。因此,如果所有数字都相同或字符串中没有数字,则输出为 1.0,即这是一个无效标识符。请注意,分母是位数(如果有)。非数字不参与计算,但在我考虑的字符串中它们是非常真实的。如果需要进一步澄清,请告诉我。我在问题正文中添加了说明。
标签: r string performance max digits