Numpy 避免Nan计算

Numpy 避免Nan计算,numpy,nan,Numpy,Nan,有人能帮我吗?我试图在结果列表中避免nan值。因为如果p太接近于零,它将在我的新列表中生成nan import random import numpy as np from numpy import log def Compute(ListA): NewListA = [] p = random.random() for item in ListA: u=np.exp(-(float(item)/500)**1.2) y=500*((

有人能帮我吗?我试图在结果列表中避免nan值。因为如果p太接近于零,它将在我的新列表中生成nan

import random
import numpy as np
from numpy import log 


def Compute(ListA):
    NewListA = []
    p = random.random()
    for item in ListA:
        u=np.exp(-(float(item)/500)**1.2)
        y=500*((np.log(1/(u*(1-p))))**(1/1.2))
        while y == nan:
            continue
        else:
            y=500*((np.log(1/(u*(1-p))))**(1/1.2))
            NewListA.append(y)
    return NewListA

ListA = [2.00345, 0.004, 3.0876, 6.00034, 8.0777, 9.444, 0.0004, 11.000678]
print (Compute(ListA))

在pythonshell中,尝试以下操作

np.nan == np.nan
查看结果,然后思考这对
while
循环意味着什么

提示:有一个函数是有原因的

您的其他问题与nan无关。事实上,你发布的版本并不遥远。 您希望
Compute
函数为原始列表中的每个值计算一个新值。新值具有随机分量,但也取决于旧值的某些公式

为了实现这一点,您已经正确设置了一个将旧列表作为参数的函数。在函数开头正确初始化新列表,并在旧列表上正确启动循环

现在出现了第一个问题:对于循环的每个元素,都需要一个新的随机数。循环是局部的,它们只适用于内部。python中的Inside是指带有
for
语句的行后面的缩进块中的in。因此:

- where has the line marked (1) to be placed?
由于您的nan问题,您必须先检查每个新值,然后才能接受它,并且只要它是nan,您就必须重复计算新值。为此,您设置了一个while循环。只要新值为nan,就应重复此操作。但正如我们所讨论的,你无法与nan相比。nan代表“不是数字”。两个都不是数字的东西不必相等。因此,将nan与nan或任何东西进行比较都不会返回真值。为了仍然能够检查nan,有一个名为isnan的专用函数。你必须在这里使用它。因此

- how must the line marked (2) be modified?
“继续”的说法是胡说八道。你没有设置while循环只是为了在第一个拐角处跳出来。循环的目的是重新尝试计算新值,因此必须绘制一个新的随机数,然后再次进行计算。因此

- which two lines do you have to copy and use to replace the bogus continue statement marked (3)?
不需要else子句,请将其删除。您现在处于for循环的末尾,内部while循环已经终止。请记住,当且仅当循环条件为False时才会发生这种情况

- what does that mean for `y`? Can it still be `nan` at this point?
根据最后一个答案,接下来的两个操作中只有一个有意义:a)计算新的
y
,b)接受当前的
y
,并将其存储在输出列表中,因此

- which of the lines (4, 5) do you need to keep, which do you need to delete?
别忘了把那条线取消一级;否则计算机会认为它属于while循环

祝贺您,您的程序现在应该可以运行了

import random
import numpy as np
from numpy import log 


def Compute(ListA):
    NewListA = []
    p = random.random()  # (1)
    for item in ListA:
        u=np.exp(-(float(item)/500)**1.2)
        y=500*((np.log(1/(u*(1-p))))**(1/500))
        while y == nan:  # (2)
            continue     # (3)
        else:
            y=500*((np.log(1/(u*(1-p))))**(1/500))  # (4)
            NewListA.append(y)                      # (5)
    return NewListA

ListA = [2.00345, 0.004, 3.0876, 6.00034, 8.0777, 9.444, 0.0004, 11.000678]
print (Compute(ListA))

使用
if
代替
while
;和
isnan
而不是
==nan

    if np.isnan(y):   #while y == nan:
        continue
    NewListA.append(y)   # don't need to repeat y calc?
您想跳过此
而不是在
y
上进行一些新的迭代。当我使用你的语法时,我陷入了一个无限循环中,我不得不杀死它

In [324]: for item in range(10):
     ...:     while item==5:
     ...:         continue
     ...:     else:
     ...:         print(item)
     ...:         
0
1
2
3
4
<infinite loop>
continue
块的替代选项

for item ...
    y = ....
    if not np.isnan(y):
       newList.append(y)

这是另一个可行的解决方案。它产生可预测长度的输出(等于输入的长度)


这是问题的答案。正如Paul所说,我想保持while循环更合适。但这两种代码都有效。谢谢你们

import random
import numpy as np
from numpy import log 

def Compute2(ListA):
    NewListB = []
    p = random.random()   
    for item in ListA:
        u=np.exp(-(float(item)/500)**1.2)
        y=500*((np.log(1/(u*(1-p))))**(1/1.2))
        while np.isnan(y):   
            continue      
        else:
            y=500*((np.log(1/(u*(1-p))))**(1/1.2))
            NewListB.append(y)                      
    return NewListB

ListB = [2.00345, 0.004, 3.0876, 6.00034, 8.0777, 9.444, 0.0004, 11.000678]
print (Compute2(ListB))

我修复了你问题中的代码格式,下次请在发布前使用实时预览。我不知道你是怎么得到nan的。次要提示:您的代码中有一些不必要的东西:要么导入
uniform
并称之为
uniform
,要么导入
random
并使用
random.uniform
。还有一个
np.random.uniform
可能适合你,那么你不需要导入除numpy以外的任何东西。你最新的编辑破坏了我修复的格式。这次请自己通过ing更正。谢谢Andras DeakAndras,这个列表是变化的。事实上,我想计算一个左截断的逆威布尔随机变量。如您所见,如果日志中的值太接近于零或1,我会得到一些条目列表的NaN。您缺少为每个列表元素生成新随机数的循环。您需要
为列表中的
生成一个随机数,
中断
,以防得到一个好的随机数。另一个选项是限制统一数字以避免接近0,在这种情况下,您可以使用
np.random.uniform(minval,maxval,len(ListA))
一次生成所有数字。这不是问题的答案。@AndrasDeak更好吗?我试图用一种能让它坚持下去的方式来传达一些重要的东西。虽然从技术角度来说,这不是一个答案,但它让你很容易找到它。需要阅读你的信息的人都不会偶然发现这个问题(假设这个问题两周后就会出现)。如果你想指导OP,你可以在评论中这样做。答案是否是答案完全是一个技术问题。但您的答案并不是一个有意义的答案,因为OP比按值测试NAN有更多的基本问题。这一微妙之处(无论多么重要!)离这条路还有三步之遥。@EricEnkele谁应该读到这一点?你不能至少暂时提出你的问题吗?我看到的是你仍然直接把y和nan比较。我认为我们已经就此达成了共识。此外,您似乎将相同的for循环堆叠在其自身之上。让我告诉你,这通常不是一个好主意。@EricEnkele我还没有为你修好它,但我已经给了你关于如何自己修好它的非常详细的说明。除此之外,您还可以查看hpaulj的答案以获得更多提示。看看最新的答案。非常感谢@hpaulj@hpaulj实际上,我认为保持while循环同样有意义。因为您想重试计算y,直到它通过集合,所以它有一个随机组件,所以这不一定是infinte循环。你可以软化你的“用if代替while”,但是你在
while
中做了一些改变,比如计算新的
pimport random
import numpy as np
from numpy import log 


def Compute(ListA):
    NewListA = []
    for item in ListA:
        u=np.exp(-(float(item)/500)**1.2)
        p = random.random()
        y=500*((np.log(1/(u*(1-p))))**(1/1.2))
        while np.isnan(y):
            p = random.random()
            y=500*((np.log(1/(u*(1-p))))**(1/1.2))
        NewListA.append(y)
    return NewListA

ListA = [2.00345, 0.004, 3.0876, 6.00034, 8.0777, 9.444, 0.0004, 11.000678]
print (Compute(ListA))
import random
import numpy as np
from numpy import log 

def Compute2(ListA):
    NewListB = []
    p = random.random()   
    for item in ListA:
        u=np.exp(-(float(item)/500)**1.2)
        y=500*((np.log(1/(u*(1-p))))**(1/1.2))
        while np.isnan(y):   
            continue      
        else:
            y=500*((np.log(1/(u*(1-p))))**(1/1.2))
            NewListB.append(y)                      
    return NewListB

ListB = [2.00345, 0.004, 3.0876, 6.00034, 8.0777, 9.444, 0.0004, 11.000678]
print (Compute2(ListB))