AJE*_*Map 6 python arrays interpolation numpy median
我有一个1维数据集,其中一些没有数据值设置为9999.这是一个提取,因为它很长:
this_array = [ 4, 4, 1, 9999, 9999, 9999, -5, -4, ... ]
Run Code Online (Sandbox Code Playgroud)
我想用任何一侧最接近的值的平均值替换无数据值,但是由于有些数据值没有最接近的值也没有数据值,因此替换它们有点困难.即我希望三个没有数据值被-2替换.我创建了一个循环来遍历数组中的每个标量并测试没有数据:
for k in this_array:
if k == 9999:
temp = np.where(k == 9999, (abs(this_array[k-1]-this_array[k+1])/2), this_array[k])
else:
pass
this_array[k] = temp
Run Code Online (Sandbox Code Playgroud)
但是我需要添加一个if函数或方法来获取k-1之前或k + 1之后的值,如果它也等于9999,例如:
if np.logical_or(k+1 == 9999, k-1 == 9999):
temp = np.where(k == 9999, (abs(this_array[k-2]-this_array[k+2])/2), this_array[k])
Run Code Online (Sandbox Code Playgroud)
可以看出,这个代码变得混乱,因为最终可能会得到错误的值或者最后加载嵌套的if函数.有没有人知道一种更简洁的方法来实现它,因为它在整个数据集中变化很大?
根据要求:如果第一个和/或最后一个点不是数据,则最好用最近的数据点替换它们.
可能有一种更有效的方法可以使用 numpy 函数来执行此操作,但这里是使用itertools 模块的解决方案:
from itertools import groupby
for k, g in groupby(range(len(this_array)), lambda i: this_array[i] == 9999):
if k:
indices = list(g)
new_v = (this_array[indices[0]-1] + this_array[indices[-1]+1]) / 2
this_array[indices[0]:indices[-1]+1].fill(new_v)
Run Code Online (Sandbox Code Playgroud)
如果最后一个元素或第一个元素可以是9999,则使用以下内容:
from itertools import groupby
for k, g in groupby(range(len(this_array)), lambda i: this_array[i] == 9999):
if k:
indices = list(g)
prev_i, next_i = indices[0]-1, indices[-1]+1
before = this_array[prev_i] if prev_i != -1 else this_array[next_i]
after = this_array[next_i] if next_i != len(this_array) else before
this_array[indices[0]:next_i].fill((before + after) / 2)
Run Code Online (Sandbox Code Playgroud)
使用第二个版本的示例:
>>> from itertools import groupby
>>> this_array = np.array([9999, 4, 1, 9999, 9999, 9999, -5, -4, 9999])
>>> for k, g in groupby(range(len(this_array)), lambda i: this_array[i] == 9999):
... if k:
... indices = list(g)
... prev_i, next_i = indices[0]-1, indices[-1]+1
... before = this_array[prev_i] if prev_i != -1 else this_array[next_i]
... after = this_array[next_i] if next_i != len(this_array) else before
... this_array[indices[0]:next_i].fill((before + after) / 2)
...
>>> this_array
array([ 4, 4, 1, -2, -2, -2, -5, -4, -4])
Run Code Online (Sandbox Code Playgroud)