检查word-Python中数字内容的百分比

检查word-Python中数字内容的百分比,python,python-2.7,python-3.x,pyspark,Python,Python 2.7,Python 3.x,Pyspark,我想检查特定字符串中数字内容的百分比。比如说, Words = ['p2', 'p23','pp34','ppp01932','boss'] 当输入是这样时,输出应该是 output 0.5 0.67 0.5 0.625 0.0 输出后面的量化是,对于p2,数字内容的数量是1,总长度是2。因此为0.5。同样,我希望找到所有条目的输出 我试过以下方法 float(sum(c.isdigit() for c in words[i])) / float(len(words[i])) 这工作正常

我想检查特定字符串中数字内容的百分比。比如说,

Words = ['p2', 'p23','pp34','ppp01932','boss']
当输入是这样时,输出应该是

output 
0.5
0.67
0.5
0.625
0.0
输出后面的量化是,对于p2,数字内容的数量是1,总长度是2。因此为0.5。同样,我希望找到所有条目的输出

我试过以下方法

float(sum(c.isdigit() for c in words[i])) / float(len(words[i]))
这工作正常,但效率非常低,而且当我使用pyspark运行它时,会出现诸如jvm错误之类的错误。我正在寻找一种有效的方法来发现这一点,这样我就可以在一个大约20亿条记录的数据集的规模数据中运行它

任何帮助都将不胜感激


谢谢

这对我很有用,你必须在python中使用正则表达式,只需导入re,因为re是用c编写的,所以速度非常好

 for i in Words:
    print float(len(''.join(re.findall('\d',i))))/float(len(i))

使用re.findall'\d',您可以在列表的每个元素中找到所有数字,使用len,如果您有1000个长度约为100或更高的正则表达式的单词,您可以根据结果得到它的大小,这似乎是最适合您的方法。

低效是您测试的东西,而不是猜测。我在这个isdigit、re.sub等上运行了几个变体,只有两件事情比您的代码快:去掉不必要的浮点,不使用I索引

例如

在一个小巧的老盒子上制作:

0.7179876668378711
0.5230729999020696
0.4444526666775346
0.3233160013332963

aaa以迄今为止最好的时间领先。酒吧老板!为每个人列出理解

你的代码实际上不适合我。不过,这似乎相当,也许会有所帮助

words = ['p2', 'p23','pp34','ppp01932','boss']
map(lambda v: sum(v)/float(len(v)) , map(lambda v: map(lambda u: u.isdigit(), v),  words))
##[0.5, 0.6666666666666666, 0.5, 0.625, 0.0]
试试这个:

Words = ['p2', 'p23','pp34','ppp01932','boss']

def get_digits(string):
    c = 0
    for i in string:
        if i.isdigit():
            c+=1
    return c
for item in Words:
    print(round(float(get_digits(item))/len(item), 2))

请注意,这一点已从答案添加到此处提出的许多有趣的方法中,并且基于一些摆弄,看起来每个方法的相关时间可能会根据所考虑的单词长度而有相当大的波动

让我们抓住一些建议的解决方案进行测试:

定义原文: [sumc.isdigit表示单词中的c/floatlenword表示单词中的单词] def筛选的_列表_理解词: [len[c.isdigit时用c表示单词中的c]/lenword表示单词中的c] def regexwords: [len.joinre.findall\d,逐字/逐字逐句] def本机过滤器单词: [lenfilterstr.isdigit,word/floatlenword逐字逐句] def native_filter_与_映射词: maplambda word:lenfilterstr.isdigit,word/floatlenword,word 并用不同的字长对它们进行测试。时间以秒为单位。 测试长度为10的1000个单词:

                    original:       1.976
 filtered_list_comprehension:       1.224
                       regex:       2.575
               native_filter:       1.209
      native_filter_with_map:       1.264
测试长度为20的1000个单词:

                    original:       3.044
 filtered_list_comprehension:       2.032
                       regex:       3.205
               native_filter:       1.947
      native_filter_with_map:       2.034
用长度为30的1000个单词进行测试:

                    original:       4.115
 filtered_list_comprehension:       2.819
                       regex:       3.889
               native_filter:       2.708
      native_filter_with_map:       2.734
使用长度为50的1000个单词进行测试:

                    original:       6.294
 filtered_list_comprehension:       4.313
                       regex:       4.884
               native_filter:       4.134
      native_filter_with_map:       4.171
测试长度为100的1000个单词:

                    original:       11.638
 filtered_list_comprehension:       8.130
                       regex:       7.756
               native_filter:       7.858
      native_filter_with_map:       7.790
使用长度为500的1000个单词进行测试:

                    original:       55.100
 filtered_list_comprehension:       38.052
                       regex:       28.049
               native_filter:       37.196
      native_filter_with_map:       37.209

从这一点我可以得出结论,如果你要测试的单词可以长达500个字符左右,正则表达式似乎工作得很好。否则,对于各种长度,使用str.isdigit进行过滤似乎是最好的方法。

提示:您可以通过使用本地名称查找替换内置查找来加快代码的速度

这是我最快的解决方案:

def count(len=len):
    for word in words:
        len([c for c in word if c.isdigit()]) / len(word)
这基本上是哈姆斯的过滤列表理解/Peter的isdigsub4,带有len=len优化


使用此技巧,您的操作码将只使用LOAD_FAST而不是LOAD_GLOBAL。这给了我3.6%的加速。不多,但总比没有好。

regex将比处理OP的简单字符串要慢得多doing@Hamms,抛开不必要的浮点值,我发现,对于10个字符的短字母数字字符串,OP的代码比这个基于正则表达式的解决方案要好。但当字符串增加到100个字符时,基于正则表达式的解决方案明显优于OP的解决方案。我将差异归因于Python中的迭代与C中的迭代,只要字符串足够长,就可以忽略正则表达式开销。您得到了不同的计时结果吗?一些测试表明,对于30个字符或更长的字符串,regex比OP的方法快,对于40个字符或更长的字符串,regex比其他方法快,列表理解更好,但对于较短的字符串,regex比OP的方法慢两倍。因此,真正的答案将取决于OP数据的性质,如果字符串长度变长,正则表达式是最好的方法,是吗?实际上,在研究了使用map、filter和str.isdigit的方法之后,类似于maplambda word:lenfilterstr.isdigit,word/floatlenword,对于大约100个字符的字符串,words略优于regex,对于较短的字符串,words明显优于regex。虽然map应该很快,因为它是用C进行迭代的,但只有当您传递的代码也是用C编写的时,它才是一个胜利。如果您传递的是Python代码,例如lambda,则无法获得预期的速度。如果将maplambda u:u.isdigit,v替换为mapstr.isdigit,v,当测试字符串的长度达到大约100个字符时,您应该能够测量改进。使用带有过滤列表的len对我来说要快得多:len[c for c in word If c.isdigit]/lenword如上所述
谢谢。你知道,这可能会演变成某种“泡沫热”的竞赛。这当然是有趣的,也很琐碎,足以保证质量!:您是否考虑过PyPy、Cython或编写C扩展模块?
def count(len=len):
    for word in words:
        len([c for c in word if c.isdigit()]) / len(word)