问题描述
我正在尝试创建一个函数来从 Python 中的列表中减去每个元素,但是,第一个元素必须是 nan
。
这是我的功能:
def sub_vector(x):
from numpy import nan
y=[]
for j,i in enumerate(range(len(x)-1)):
z= np.nan
if j == 0:
y.append(z)
else:
val = x[i+1] - x[i]
y.append(val)
return y
响应应该是这样的:
zz = [1,2,3,4,5]
sub_vector(zz)
[nan,1,1]
But this function is returning:
[nan,1]
我的错误是什么?
解决方法
from numpy import nan
def sub_vector(x):
return [nan] + [x[i] - x[i - 1] for i in range(1,len(x))]
,
您可以将 np.diff
与 prepend=np.nan
一起使用
>>> np.diff(zz,prepend=np.nan)
array([nan,1.,1.])
您的错误是您不需要检查 0
。这是因为 enumerate(range(len(x)-1))
的结果是 [(0,0),(1,1),(2,2),(3,3)]
。所以你只迭代了四个元素,你的第一次迭代被跳过了。
放下if-else
:
def sub_vector(x):
from numpy import nan
y=[np.nan]
for j,i in enumerate(range(len(x)-1)):
val = x[i+1] - x[i]
y.append(val)
return y
>>> sub_vector(zz)
[nan,1,1]
此外,enumerate(range(len(x)-1))
是非 Python 和低效的,您可以单独使用 enumerate
,使用 start
参数。
def sub_vector(x):
from numpy import nan
y=[]
for j,_ in enumerate(x,start=-1):
if j < 0:
y.append(np.nan)
continue
val = x[j+1] - x[j]
y.append(val)
return y
>>> sub_vector(zz)
[nan,1]
如果不想使用numpy
,可以使用list comprehension
:
>>> [(zz[i] - j) if i else np.nan for i,j in enumerate(zz)]
[nan,1]
无论如何,如果您使用 numpy
,numpy.diff
是正确的选择。
您正在使用 if-else。删除其他条件和所有作品。 目前,它正在跳过循环迭代的第一次执行。
import numpy as np
def sub_vector(x):
from numpy import nan
y=[]
for j,i in enumerate(range(len(x)-1)):
z= np.nan
if j == 0:
y.append(z)
val = x[i+1] - x[i]
y.append(val)
return y
print(sub_vector([1,2,3,4,5]))
,
根本没有numpy
:
>>> from operator import sub
>>> list(map(sub,x,[float('nan'),*x])))
[nan,1]
这是有效的,因为对于任何 x - float('nan') == float('nan')
都可以减去 x
的 nan
。
list(map(sub,*x]))
== (map(sub,[1,5],5]))
== [1-float('nan'),2-1,3-2,4-3,5-4]
,
在 sub_vector 函数中,您不会迭代所有输入向量,而是迭代 len(x)-1 这意味着如果您的向量有 5 个元素,则返回向量将仅包含 4 个元素,您可以通过删除 -1 来解决此问题范围是这样的:
def sub_vector(x):
from numpy import nan
y=[]
for j,i in enumerate(range(len(x))):
z= np.nan
if j == 0:
y.append(z)
else:
val = x[i+1] - x[i]
y.append(val)
return y
你可以直接这样做
def sub_vector(x):
return [np.nan if x==0 else 1 for x in range(len(x))]