ValueError:math.log中的数学域错误,但无法弄清楚错误

时间:2018-05-24 09:38:00

标签: python python-3.x matplotlib

我正在尝试通过调用profile():

运行以下代码(来自Fastest way to check if a value exist in a list

但似乎我收到了这个错误ValueError: math domain error,而我的朋友说他可以毫无问题地运行它。预期结果是三种方法的图表。

我认为问题出现在math.log中,这可能取决于随机值。

time_method_in.append(math.log(method_in(a,b,c)))
time_method_set_in.append(math.log(method_set_in(a,b,c)))
time_method_bisect.append(math.log(method_bisect(a,b,c)))

我感觉到错误,因为该值为负值或以太精确的精度划分。所以,我试图使用log10和decimal,但这些方法似乎都不起作用。

有什么我应该进一步尝试的吗?非常感谢你。

import random
import bisect
import matplotlib.pyplot as plt
import math
import time

def method_in(a,b,c):
    start_time = time.time()
    for i,x in enumerate(a):
        if x in b:
            c[i] = 1
    return(time.time()-start_time)   

def method_set_in(a,b,c):
    start_time = time.time()
    s = set(b)
    for i,x in enumerate(a):
        if x in s:
            c[i] = 1
    return(time.time()-start_time)

def method_bisect(a,b,c):
    start_time = time.time()
    b.sort()
    for i,x in enumerate(a):
        index = bisect.bisect_left(b,x)
        if index < len(a):
            if x == b[index]:
                c[i] = 1
    return(time.time()-start_time)

def profile():
    time_method_in = []
    time_method_set_in = []
    time_method_bisect = []

    Nls = [x for x in range(1000,20000,1000)]
    for N in Nls:
        a = [x for x in range(0,N)]
        random.shuffle(a)
        b = [x for x in range(0,N)]
        random.shuffle(b)
        c = [0 for x in range(0,N)]

        time_method_in.append(math.log(method_in(a,b,c)))
        time_method_set_in.append(math.log(method_set_in(a,b,c)))
        time_method_bisect.append(math.log(method_bisect(a,b,c)))

    plt.plot(Nls,time_method_in,marker='o',color='r',linestyle='-',label='in')
    plt.plot(Nls,time_method_set_in,marker='o',color='b',linestyle='-',label='set')
    plt.plot(Nls,time_method_bisect,marker='o',color='g',linestyle='-',label='bisect')
    plt.xlabel('list size', fontsize=18)
    plt.ylabel('log(time)', fontsize=18)
    plt.legend(loc = 'upper left')
    plt.show()

编辑:正如gazoh回答的那样,我现在将使用他的工作。但是,如果我有更多的Python和PyPlot经验,我将来会再次访问和更新它。非常感谢你。

1 个答案:

答案 0 :(得分:0)

第一次调用method_in时,当我尝试运行您的代码时,它会返回0.0,因此会出错。您应该实现一种处理此案例的方法。 或者,您可以不计算值的对数,并使用matplotlib的semilogy()以对数比例绘制您的图:

plt.semilogy(Nls,time_method_in,marker='o',color='r',linestyle='-',label='in')
plt.semilogy(Nls,time_method_set_in,marker='o',color='b',linestyle='-',label='set')
plt.semilogy(Nls,time_method_bisect,marker='o',color='g',linestyle='-',label='bisect')
plt.xlabel('list size', fontsize=18)
plt.ylabel('time', fontsize=18)
plt.legend(loc = 'upper left')
plt.show()