[英]Inserting rows of zeros at specific places along the rows of a NumPy array
我有一个两列numpy数组。 我想通过第2列的每一行,并取每组2个数字(9.6-0,19.13-9.6等)之间的差异。 如果差值> 15,我想为两列插入一行0。 我真的只需要在第一列中结束值(我只需要第二列来确定将0放在哪里),所以如果更容易将它们拆分,那就没问题了。
这是我的输入数组:
[[0.00 0.00]
[1.85 9.60]
[2.73 19.13]
[0.30 28.70]
[2.64 38.25]
[2.29 47.77]
[2.01 57.28]
[2.61 66.82]
[2.20 76.33]
[2.49 85.85]
[2.55 104.90]
[2.65 114.47]
[1.79 123.98]
[2.86 133.55]]
它应该变成:
[[0.00 0.00]
[1.85 9.60]
[2.73 19.13]
[0.30 28.70]
[2.64 38.25]
[2.29 47.77]
[2.01 57.28]
[2.61 66.82]
[2.20 76.33]
[2.49 85.85]
[0.00 0.00]
[2.55 104.90]
[2.65 114.47]
[1.79 123.98]
[2.86 133.55]]
你可以使用ediff1d
, argmax
和numpy
insert
进行ediff1d
argmax
:
np.insert(arr, np.argmax(np.append(False, np.ediff1d(arr[:,1])>15)), 0, axis=0)
#array([[ 0. , 0. ],
# [ 1.85, 9.6 ],
# [ 2.73, 19.13],
# [ 0.3 , 28.7 ],
# [ 2.64, 38.25],
# [ 2.29, 47.77],
# [ 2.01, 57.28],
# [ 2.61, 66.82],
# [ 2.2 , 76.33],
# [ 2.49, 85.85],
# [ 0. , 0. ],
# [ 2.55, 104.9 ],
# [ 2.65, 114.47],
# [ 1.79, 123.98],
# [ 2.86, 133.55]])
假设A
作为输入数组,这里是一个基于零初始化的矢量化方法 -
# Get indices at which such diff>15 occur
cut_idx = np.where(np.diff(A[:,1]) > 15)[0]
# Initiaize output array
out = np.zeros((A.shape[0]+len(cut_idx),2),dtype=A.dtype)
# Get row indices in the output array at which rows from A are to be inserted.
# In other words, avoid rows to be kept as zeros. Finally, insert rows from A.
idx = ~np.in1d(np.arange(out.shape[0]),cut_idx + np.arange(1,len(cut_idx)+1))
out[idx] = A
样本输入,输出 -
In [50]: A # Different from the one posted in question to show variety
Out[50]:
array([[ 0. , 0. ],
[ 1.85, 0.6 ],
[ 2.73, 19.13],
[ 2.2 , 76.33],
[ 2.49, 85.85],
[ 2.55, 104.9 ],
[ 2.65, 114.47],
[ 1.79, 163.98],
[ 2.86, 169.55]])
In [51]: out
Out[51]:
array([[ 0. , 0. ],
[ 1.85, 0.6 ],
[ 0. , 0. ],
[ 2.73, 19.13],
[ 0. , 0. ],
[ 2.2 , 76.33],
[ 2.49, 85.85],
[ 0. , 0. ],
[ 2.55, 104.9 ],
[ 2.65, 114.47],
[ 0. , 0. ],
[ 1.79, 163.98],
[ 2.86, 169.55]])
a=[[0.00, 0.00],
[1.85, 9.60],
[2.73, 19.13],
[0.30, 28.70],
[2.64, 38.25],
[2.29, 47.77],
[2.01, 57.28],
[2.61, 66.82],
[2.20, 76.33],
[2.49, 85.85],
[2.55, 104.90],
[2.65, 114.47],
[1.79, 123.98],
[2.86, 133.55]]
i=0
while i <len(a)-1:
if (a[i+1][1]-a[i][1])>15:
a.insert(i+1,[0,0])
i=i+1
i=i+1
for line in a :
print line
输出:
[0.0, 0.0]
[1.85, 9.6]
[2.73, 19.13]
[0.3, 28.7]
[2.64, 38.25]
[2.29, 47.77]
[2.01, 57.28]
[2.61, 66.82]
[2.2, 76.33]
[2.49, 85.85]
[0, 0]
[2.55, 104.9]
[2.65, 114.47]
[1.79, 123.98]
[2.86, 133.55]
这是正确的算法:
arr = [ ... ]
result = []
result.append(arr[0])
for i in range(1, len(arr)):
if arr[i][1] - arr[i-1][1] > 15:
result.append([0.0,0.0])
result.append(arr[i])
print(result)
一个可以处理多个填充槽的衬垫。 在这里,我在OP示例中测试它,其中包含一个修改后的值。
In [70]: np.insert(a, np.where(np.diff(a[:,1])>15)[0]+2,0, axis=0)
In [71]: Out[70]:
array([[ 0. , 0. ],
[ 1.85, 9.6 ],
[ 2.73, 19.13],
[ 0.3 , 28.7 ],
[ 2.64, 38.25],
[ 2.29, 140. ], # modified
[ 0. , 0. ],
[ 2.01, 57.28],
[ 2.61, 66.82],
[ 2.2 , 76.33],
[ 2.49, 85.85],
[ 2.55, 104.9 ],
[ 0. , 0. ],
[ 2.65, 114.47],
[ 1.79, 123.98],
[ 2.86, 133.55]])
使用where
而不是argmax
( Colonel's
答案)处理多个槽。 +2
是必需的,因为diff
是一个short,我们之后插入。 ediff1d
有更多处理端点的选项。
np.insert
有各种填充策略。 在这种情况下,它可能正在做类似于Divakar's
答案 - 创建一个out
,并将值复制到正确的插槽。
另一个答案使用np.abs()
。 这可能是需要的,但在我的例子中,在140
回落到57
后会增加另外0
行。
如果numpy
没有一些本地方法来做这类事情我会感到惊讶但我认为这也会有用:
i = 1
while i < len(lst):
if abs(lst[i][1] - lst[i-1][1]) > 15:
lst[i] = [0.0, 0.0]
# uncomment to change only the second column
# lst[i][1] = 0.0
i += 1
i += 1
输出:
>>> lst
array([[ 0. , 0. ],
[ 1.85, 9.6 ],
[ 2.73, 19.13],
[ 0.3 , 28.7 ],
[ 2.64, 38.25],
[ 2.29, 47.77],
[ 2.01, 57.28],
[ 2.61, 66.82],
[ 2.2 , 76.33],
[ 2.49, 85.85],
[ 2.55, 104.9 ],
[ 2.65, 114.47],
[ 1.79, 123.98],
[ 2.86, 133.55]])
>>>
>>> i = 1
>>> while i < len(lst):
... if abs(lst[i][1] - lst[i-1][1]) > 15:
... lst[i] = [0.0, 0.0]
... i += 1
... i += 1
...
>>> lst
array([[ 0. , 0. ],
[ 1.85, 9.6 ],
[ 2.73, 19.13],
[ 0.3 , 28.7 ],
[ 2.64, 38.25],
[ 2.29, 47.77],
[ 2.01, 57.28],
[ 2.61, 66.82],
[ 2.2 , 76.33],
[ 2.49, 85.85],
[ 0. , 0. ],
[ 2.65, 114.47],
[ 1.79, 123.98],
[ 2.86, 133.55]])
>>>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.