检查单词Python中数字内容的百分比

2024-05-13 19:37:44 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

当输入是这样的时候,输出应该是

^{pr2}$

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

我试过以下方法

float(sum(c.isdigit() for c in words[i])) / float(len(words[i]))

这是很好的工作,但它是非常低效的,而且当我使用pyspark运行它时,我会得到诸如jvm错误之类的错误。我正在寻找一种有效的方法来找出这个问题,这样我就可以在一个大约20亿条记录的数据集中运行它。在

任何帮助都将不胜感激。在

谢谢


Tags: 方法字符串内容错误数字float百分比words
3条回答

这里提出了这么多有趣的方法,基于对它的一些修改,看起来每种方法的相对时间可以根据所考虑单词的长度而有很大的波动。在

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

def original(words):
    [sum(c.isdigit() for c in word) / float(len(word)) for word in words]


def filtered_list_comprehension(words):
    [len([c for c in word if c.isdigit()]) / len(word) for word in words]


def regex(words):
    [len("".join(re.findall("\d", word))) / float(len(word)) for word in words]


def native_filter(words):
    [len(filter(str.isdigit, word)) / float(len(word)) for word in words]


def native_filter_with_map(words):
    map(lambda word: len(filter(str.isdigit, word))/float(len(word)), words)

用不同的字长来测试它们。时间以秒为单位。 用1000个单词进行测试,长度为10:

^{pr2}$

用1000个单词进行测试,长度为20:

                    original:       3.044
 filtered_list_comprehension:       2.032
                       regex:       3.205
               native_filter:       1.947
      native_filter_with_map:       2.034

测试1000个单词,长度30:

^{4}$

用1000个单词进行测试,长度为50:

                    original:       6.294
 filtered_list_comprehension:       4.313
                       regex:       4.884
               native_filter:       4.134
      native_filter_with_map:       4.171

1000字100字测试:

                    original:       11.638
 filtered_list_comprehension:       8.130
                       regex:       7.756
               native_filter:       7.858
      native_filter_with_map:       7.790

用1000个单词进行测试,长度为500:

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

从这一点我可以得出结论,如果你的“单词”被测试的长度可以达到500个字符左右,正则表达式似乎可以很好地工作。否则,filter与{}结合似乎是各种长度的最佳方法。在

“低效”是你测试的东西,而不是猜测。我对此运行了几个变体(isdigit()re.sub(),等等),只有两件事比代码更快:去掉不必要的float(),并且不使用i索引。在

例如

import timeit

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

def isdigsub():
    for i in range(len(words)):
        float(sum(c.isdigit() for c in words[i])) / float(len(words[i]))

def isdigsub2():
    for i in range(len(words)):
        sum(c.isdigit() for c in words[i]) / len(words[i])

def isdigsub3():
    for w in words:
        sum(c.isdigit() for c in w) / len(w)

def isdigsub4():
    # From user Hamms
    for w in words:
        len([c for c in w if c.isdigit()]) / len(w)

if __name__ == '__main__':

    print(timeit.timeit('isdigsub()', setup="from __main__ import isdigsub", number=10000))
    print(timeit.timeit('isdigsub2()', setup="from __main__ import isdigsub2", number=10000))
    print(timeit.timeit('isdigsub3()', setup="from __main__ import isdigsub3", number=10000))
    print(timeit.timeit('isdigsub4()', setup="from __main__ import isdigsub4", number=10000))

在一个破旧的小盒子上:

^{pr2}$

aaa和{a1}是目前为止最好的领先者。酒保!列出每个人的理解!在

对我来说,你必须在python中使用正则表达式,import re,而且由于{}是用c编写的,所以它的速度非常快

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

使用re.findall('\d',i)您可以找到列表中每个元素中的所有数字,而使用len()可以根据结果获得它的大小,如果您有1000个单词,长度为~100或更高的regex似乎是您的最佳方式

相关问题 更多 >