【问题标题】:Optimization error on random word splitting function Python随机分词函数Python的优化错误
【发布时间】:2015-09-21 17:09:55
【问题描述】:

我写了一个分词功能。它将一个单词分成随机字符。例如,如果输入是“运行时”,则可能是以下每个输出之一:

['runtime']
['r','untime']
['r','u','n','t','i','m','e']
....

但是当我想拆分 100k 字时,它的运行时间非常高,您有什么建议可以优化或写得更聪明。

def random_multisplitter(word):
    from numpy import mod
    spw = []
    length = len(word)
    rand = random_int(word)
    if rand == length:       #probability of not splitting
        return [word]

    else:
        div = mod(rand, (length + 1))  #defining division points 
        bound = length - div
        spw.append(div)
        while div != 0:
            rand = random_int(word)
            div = mod(rand,(bound+1))
            bound = bound-div
            spw.append(div)
        result = spw
    b = 0
    points =[]
    for x in range(len(result)-1): #calculating splitting points 
        b=b+result[x]
        points.append(b)
    xy=0
    t=[]
    for i in points:
        t.append(word[xy:i])
        xy=i
    if word[xy:len(word)]!='':
        t.append(word[xy:len(word)])
    if type(t)!=list:
        return [t]
    return t

【问题讨论】:

  • 您真的需要同时使用所有不同的版本吗? 为了什么?基于迭代器而不是列表肯定会节省内存。
  • 如果你有工作代码并且只对优化/改进感兴趣,Code Reviewstackexchange 可能是一个更好的发帖地点,可以查看他们的requirements
  • 谢谢,我会检查迭代器。它一次返回一个版本,我猜代码可能更聪明,但我现在找不到方法。
  • 您期望什么样的随机分布?所有可能的拆分是否都打算以相等的概率返回?您的random_int 函数是做什么的(它似乎将字符串作为参数并返回一个整数)?如果我正在实现这一点,并且想要一个统一的分布,我会选择一个介于 0 和 2**len(word) - 1 之间的统一随机整数,并在任何位置进行拆分。
  • random_int 只返回一个介于 0-len(word) 之间的数字,我的情况是通过生成数字从右向左拆分单词,直到没有字符为止。例如: start 'Runtime' 'run' 'time' 随机数 == 3 't' 'ime' 随机数 == 1 'ime' 随机数 == 3 (不拆分) return ['run' 't' ' ime'] 在这种情况下,每个可能的输出都有相同的概率

标签: python optimization random split word


【解决方案1】:

我不明白你在做什么,但结果绝对不是你的代码同样可能。因此代码不起作用,实际上 StackOverflow 可能是正确的地方,即使您不知道它。
我怎么知道你的代码不起作用? Law of Large Numbers!它看起来很可疑,所以我刚刚用你的函数生成了一百万个样本并得到了这个分布:

请注意,y 轴的缩放比例是对数的,这些估计的概率变化很大

所以现在一些代码既快得多,实际上也产生了同样可能的结果:

def random_multisplitter(word):
    # add's bits will tell whether a char shall be added to last substring or
    # be the beginning of its own substring
    add = random.randint(0, 2**len(word) - 1)

    # append 0 to make sure first char is start of first substring
    add <<= 1

    res = []
    for char in word:
        # see if last bit is 1
        if add & 1:
            res[-1] += char
        else:
            res.append(char)
        # shift to next bit
        add >>= 1

    return res

这就是 Blckknght 的建议,不管你信不信,我在他们发表评论前一个小时就有了同样的想法,但我没有时间写这个答案。
无论如何,这是该函数的估计概率:

全部聚集在 1/64=0.015625(绿线)附近,表明概率分布是均匀的。

我的机器上使用 python2.7 的时间对于这个函数是 4.56 µs,对于你的函数是 20.1 µs。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-09-24
  • 1970-01-01
  • 2017-10-19
  • 2020-07-17
  • 1970-01-01
  • 2021-01-19
  • 1970-01-01
  • 2016-07-24
相关资源
最近更新 更多