【问题标题】:When I am iterating through each element in a list, I am getting a list with 'nan' elements, why?当我遍历列表中的每个元素时,我得到一个包含“nan”元素的列表,为什么?
【发布时间】:2020-05-10 14:48:06
【问题描述】:

我试图通过使用 for 循环遍历列表中的每个元素来将列表中的每个元素相乘。这是我的代码:

from __future__ import division
import numpy as np
import matplotlib.pyplot as plt

data = np.genfromtxt('spec.txt') #Reading in the text file
frequency_data = data[:,0] 

h = 6.626e-27 #Planck constant in erg s
c = 2.998e10 #speed of light (in vacuum) in cm/s
k = 1.381e-16 



def Bv(v,T):                
    k1 = (2.0*h)/(c**2)
    x2 = (h*v)/(k*T)
    return k1*((v**3)/(np.exp(x2) -1)) 

我尝试遍历列表中的每个元素
Bv(frequency_data, 2.275)

BB_v = []

for k in range(len(frequency_data)):
    c = Bv(frequency_data, 2.275)[k]*10**17
    BB_v.append(c)

print(BB_v)

输出:

[0.0, inf, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 
 nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 
 nan, nan, nan, nan, nan, nan, nan]

/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:7: RuntimeWarning: divide 
by zero encountered in true_divide
import sys/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:6:RuntimeWarning: 
divide by zero encountered in double_scalars

但我得到了一个包含“nan”元素的列表。为什么我会得到一个包含“nan”元素的列表?

Link to the data

【问题讨论】:

  • 找我好像你想做for k in Bv(frequency_data, 2.275): BB_v.append(k*10**17)?
  • 我们没有您的输入数据,请向minimal reproducible example 提供一些硬编码数据以复制您的错误并建议如何修复它。
  • 嗨,我已经减少了我的代码并提供了输入数据。请检查。

标签: python arrays python-3.x for-loop


【解决方案1】:

这与迭代无关,因为我们可以只用一个值重现问题。

x2 的值非常接近于零,导致分母 np.exp(x2)-1 由于机器精度而在数值上等于零:

def Bv(v,T):                
    k1 = (2.0*h)/(c**2)
    x2 = (h*v)/(k*T)
    print("x2={}".format(x2))
    return k1*((v**3)/(np.exp(x2) -1)) 


print(Bv(1., 2.275))

给出结果:

x2=4.160753532182104e-28
nan

/snap/jupyter/6/lib/python3.7/site-packages/ipykernel_launcher.py:5: RuntimeWarning: divide by zero encountered in double_scalars

为避免这种情况,您应该重写 Bv 中分数的公式,使其在数值上与 x2 的小值兼容。例如,您可以在零附近进行泰勒展开:

np.exp(x) 当 x 趋于 0 时趋于 1+x

所以 np.exp(x)-1 应该倾向于 x

【讨论】:

    【解决方案2】:

    看起来你的两个大问题是:

       c = Bv(...) # <-- you are overwriting the constant c here
    

        x2 = (...*...)/(k*...) # <-- you use k here instead of perhaps k1?
    

    如果你在同一个模块中运行这一切,那么k 将是一个在你的 for 循环中定义为0 的全局变量。因此,在第一次迭代中,x2 将评估为一个零数组。这意味着返回值将是一个无穷大数组 (&lt;float&gt; / 0)。 c == np.array([inf, ...]) 末尾的含义。最后,这意味着在第二次迭代中,k1 的计算结果为0&lt;float&gt; / c**2,其中c=inf)。这意味着您的 return 语句计算结果为 inf / 0,这会产生您的“非数字”结果。

    要修复,您至少需要执行以下操作之一:

    • ALL_CAPS 用于常量名称 - 更难意外覆盖它们
    • 选择更详细的变量名称,这样您就不太可能出现名称冲突(根据常量c(光速)和临时变量c(用于存储Bv(...) 的结果)。李>
    • 在函数中而不是在全局/模块范围内编写所有逻辑。这将有助于避免函数拾取在全局/模块范围内定义的非常量变量(例如,来自 for 循环的 k)。

    其次,您需要在此语句x2 = (h*v)/(k*T) 中评估是否需要k1k(请参阅第二点,关于选择更详细的变量名称以避免名称冲突)。

    【讨论】:

      猜你喜欢
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-08
      • 2018-03-14
      相关资源
      最近更新 更多