rob*_*ntw 19 python arrays numpy nan
我有一个NumPy数组a,如下所示:
>>> str(a)
'[ nan nan nan 1.44955726 1.44628034 1.44409573\n 1.4408188 1.43657094 1.43171624 1.42649744 1.42200684 1.42117704\n 1.42040255 1.41922908 nan nan nan nan\n nan nan]'
Run Code Online (Sandbox Code Playgroud)
我想用最接近的非NaN值替换每个NaN,以便开头的1.449...所有NaN都被设置为并且最后的所有NaN都被设置为1.419....
我可以看到如何针对这样的特定情况执行此操作,但我需要能够对任何长度的数组执行此操作,在数组的开头和结尾处有任何长度的NaN(在该数组中没有NaN)中间的数字).有任何想法吗?
我可以很容易地找到NaN np.isnan(),但我无法弄清楚如何获得每个NaN最接近的值.
Joe*_*ton 39
作为替代解决方案(这将对NaN中间的数组进行线性插值):
import numpy as np
# Generate data...
data = np.random.random(10)
data[:2] = np.nan
data[-1] = np.nan
data[4:6] = np.nan
print data
# Fill in NaN's...
mask = np.isnan(data)
data[mask] = np.interp(np.flatnonzero(mask), np.flatnonzero(~mask), data[~mask])
print data
Run Code Online (Sandbox Code Playgroud)
这会产生:
[ nan nan 0.31619306 0.25818765 nan nan
0.27410025 0.23347532 0.02418698 nan]
[ 0.31619306 0.31619306 0.31619306 0.25818765 0.26349185 0.26879605
0.27410025 0.23347532 0.02418698 0.02418698]
Run Code Online (Sandbox Code Playgroud)
NPE*_*NPE 21
我想用最接近的非NaN值替换每个NaN ...数字中间没有NaN
以下将这样做:
ind = np.where(~np.isnan(a))[0]
first, last = ind[0], ind[-1]
a[:first] = a[first]
a[last + 1:] = a[last]
Run Code Online (Sandbox Code Playgroud)
这是一个直接的numpy解决方案,不需要Python循环,没有递归,没有列表推导等.
NaNs 有一个有趣的特性,就是比较不同自己,因此我们可以快速找到非 nan 元素的索引:
idx = np.nonzero(a==a)[0]
Run Code Online (Sandbox Code Playgroud)
现在很容易用所需的值替换 nans:
for i in range(0, idx[0]):
a[i]=a[idx[0]]
for i in range(idx[-1]+1, a.size)
a[i]=a[idx[-1]]
Run Code Online (Sandbox Code Playgroud)
最后,我们可以把它放在一个函数中:
import numpy as np
def FixNaNs(arr):
if len(arr.shape)>1:
raise Exception("Only 1D arrays are supported.")
idxs=np.nonzero(arr==arr)[0]
if len(idxs)==0:
return None
ret=arr
for i in range(0, idxs[0]):
ret[i]=ret[idxs[0]]
for i in range(idxs[-1]+1, ret.size):
ret[i]=ret[idxs[-1]]
return ret
Run Code Online (Sandbox Code Playgroud)
编辑
哎哟,来自 C++ 我总是忘记列表范围......@aix 的解决方案比我的 C++ish 循环更优雅和高效,使用它而不是我的。
| 归档时间: |
|
| 查看次数: |
17859 次 |
| 最近记录: |