admin管理员组文章数量:1417691
Given an array that looks like this:
values [0, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 0, 0, 1, 2, 3]
index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
If I search for index 3, I want to get the indexes of the start and end indexes for that counter, before it is reset again, which is 2 - 6.
And for index 10, I want to get 8 - 13. And for index 16, I want to get 16 - 18.
How can I achieve this in numpy?
Given an array that looks like this:
values [0, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 0, 0, 1, 2, 3]
index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
If I search for index 3, I want to get the indexes of the start and end indexes for that counter, before it is reset again, which is 2 - 6.
And for index 10, I want to get 8 - 13. And for index 16, I want to get 16 - 18.
How can I achieve this in numpy?
Share Improve this question edited Jan 31 at 9:57 mkrieger1 23.6k7 gold badges64 silver badges82 bronze badges asked Jan 31 at 9:40 Andrei M.Andrei M. 4133 silver badges10 bronze badges 2 |4 Answers
Reset to default 4For example, if you care about index==10
, you can try
grp = np.cumsum(np.append(1,np.diff(values)<0))
np.argwhere(grp ==grp[index==10])[1:].T
which gives
array([[ 8, 9, 10, 11, 12, 13]])
Data
values = np.array([0, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 0, 0, 1, 2, 3])
index = np.arange(values.size)
You can get the start/end coordinates of the non-null stretches with something like:
idx = np.nonzero(values == 0)[0]
start = idx+1
end = np.r_[idx[1:]-1, len(values)-1]
m = start<end
indices = np.c_[start, end][m]
indices
:
array([[ 2, 6],
[ 8, 13],
[16, 18]])
Then get the position with searchsorted
(assuming you only pass non-zeros indices, else you need an additional check (e.g. is values[position] != 0
) and explanation of what should be the output):
indices[np.searchsorted(indices[:, 1], 2)] # [ 2, 6]
indices[np.searchsorted(indices[:, 1], 10)] # [ 8, 13]
indices[np.searchsorted(indices[:, 1], 16)] # [16, 18]
And you can get multiple targets at once:
target = [2, 6, 10, 16]
indices[np.searchsorted(indices[:, 1], target)]
array([[ 2, 6],
[ 2, 6],
[ 8, 13],
[16, 18]])
And if you have indices of zero-values you could mask them in the output:
target = [1, 2, 6, 7, 10, 16]
out = np.ma.masked_array(indices[np.searchsorted(indices[:, 1], target)],
np.broadcast_to(values[target, None]==0, (len(target), 2))
)
[[-- --]
[ 2 6]
[ 2 6]
[-- --]
[ 8 13]
[16 18]]
Used input:
values = np.array([0, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 0, 0, 1, 2, 3])
import numpy as np
arr = np.array([0, 0, 1, 2, 3, 4,5, 0, 1, 2, 3, 4, 5, 6, 0, 0,1, 2, 3])
resets = np.where(arr == 0)[0]
# Create an array of boundaries
boundaries = np.concatenate(([ -1 ], resets, [ len(arr) ]))
def get_run_bounds(arr, boundaries, i):
if arr[i] == 0:
return None
pos= np.searchsorted(boundaries, i, side='right')
start = boundaries[pos- 1] + 1
end = boundaries[pos] - 1
return (start, end)
print("Index 3→",get_run_bounds(arr, boundaries, 3)) # waiting for(2, 6)
print("Index 10 →", get_run_bounds(arr, boundaries, 10)) # (8, 13)
print("Index 16 →", get_run_bounds(arr, boundaries, 16))# (16, 18)
import numpy as np
values = np.array([0, 1, 2, 3, 4, 5, 0, 7, 8, 9, 10, 11, 12, 0, 0, 15, 16, 17])
m = values == 0
idx = np.where(m)[0]
aa = np.where(m, np.arange(len(values)), -1)
print(aa)
#[ 0 -1 -1 -1 -1 -1 6 -1 -1 -1 -1 -1 -1 13 14 -1 -1 -1]
startIdx = np.maximum.accumulate(aa, -1) +1
print(startIdx)
'''
[ 1 1 1 1 1 1 7 7 7 7 7 7 7 14 15 15 15 15]
'''
bb = np.where(m[::-1],
np.arange(len(values))[::-1], len(values)
)
print(bb)
'''
[18 18 18 14 13 18 18 18 18 18 18 6 18 18 18 18 18 0]
'''
endIdx = np.minimum.accumulate(bb)[::-1] -1
print(endIdx)
'''
[-1 5 5 5 5 5 5 12 12 12 12 12 12 12 13 17 17 17]
'''
def getRange(idx):
if values[idx] == 0 : return None
aa = int(startIdx[idx])
bb = int(endIdx[idx])
return (aa,bb)
print(getRange(3)) # Output: (1, 5)
print(getRange(10)) # Output: (7, 12)
print(getRange(16)) # Output: (15, 17)
本文标签: pythonIn an array of counters that resetfind the startend index for counterStack Overflow
版权声明:本文标题:python - In an array of counters that reset, find the start-end index for counter - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745271239a2650903.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
1
value, and goes until the next0
value occurs (or the value range ends.) So from the given start index position #3 with value2
, they want to "look back" until they find the value1
at index position #2, and look forward until they find the last non-zero number5
at index position #6. – C3roe Commented Jan 31 at 10:02