假设其中有一个浮点数的numpy数组,其中所有值都位于[0,1]
中,例如
arr = np.array([
[0.1, 0.1, 0.1, 0.4, 0.91, 0.81, 0.84], # channel 1
[0.81, 0.79, 0.85, 0.1, 0.2, 0.61, 0.91], # channel 2
[0.3, 0.1, 0.24, 0.87, 0.62, 1, 0 ], # channel 3
#...
])
,那个人想把这个秘密转换成二进制数组。可以通过以下方法轻松地完成此操作:
def binary_mask(arr, cutoff=0.5):
return (arr > cutoff).astype(int)
m = binary_mask(arr)
# array([[0, 0, 0, 0, 1, 1, 1],
# [1, 1, 1, 0, 0, 1, 1],
# [0, 0, 0, 1, 1, 1, 0]])
一个人可以通过以下方式获取1
的所有索引
for channel in m:
print(channel.nonzero())
# (array([4, 5, 6]),)
# (array([0, 1, 2, 5, 6]),)
# (array([3, 4, 5]),)
连续数字运行的一种有效方式
例如
[
[[4,6]],
[[0,2], [5,6]],
[[3,5]]
]
一个幼稚的方法可能是:
def consecutive_integers(arr):
# indexes of nonzero
nz = arr.nonzero()[0]
# storage of "runs"
runs = []
# error handle all zero array
if not len(nz):
return [[]]
# run starts with current value
run_start = nz[0]
for i in range(len(nz)-1):
# if run is broken
if nz[i]+1 != nz[i+1]:
# store run
runs.append([run_start, nz[i]])
# start next run at next number
run_start = nz[i+1]
# last run ends with last value
runs.append([run_start, nz[-1]])
return runs
print(m)
for runs in [consecutive_integers(c) for c in m]:
print(runs)
# [[0 0 0 0 1 1 1]
# [1 1 1 0 0 1 1]
# [0 0 0 1 1 1 0]]
#
# [[4, 6]]
# [[0, 2], [5, 6]]
# [[3, 5]]
答案 0 :(得分:2)
您可以比较连续的指标,然后使用where
或flatnonzero
>>> x
array([[0, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 1, 1],
[0, 0, 0, 1, 1, 1, 0]])
>>>
# find switches 0->1 and 1->0
>>> d = np.empty((np.arange(2) + x.shape), bool)
>>> d[:, 0] = x[:, 0] # a 1 in the first
>>> d[:, -1] = x[:, -1] # or last column counts as a switch
>>> d[:, 1:-1] = x[:, 1:] != x[:, :-1]
>>>
# find switch indices (of flattened array)
>>> b = np.flatnonzero(d)
# create helper array of row offsets
>>> o = np.arange(0, d.size, d.shape[1])
# split into rows, subtract row offsets and reshape into start, end pairs
>>> result = [(x-y).reshape(-1, 2) for x, y in zip(np.split(b, b.searchsorted(o[1:])), o)]
>>>
>>> result
[array([[4, 7]]), array([[0, 3],
[5, 7]]), array([[3, 6]])]
这使用python约定,即不包括右端。如果要包含右端,请改用result = [(x-y).reshape(-1, 2) - np.arange(2) for x, y in zip(np.split(b, b.searchsorted(o[1:])), o)]
。
答案 1 :(得分:1)
我会查看以下答案:https://stackoverflow.com/a/7353335/1141389
它使用np.split
答案 2 :(得分:0)
使用numpy.where
可以得到它。我已经扩展了您的数组,以尝试其他情况。
import numpy as np
def binary_mask(arr, cutoff=0.5):
return (arr > cutoff).astype(int)
arr = np.array([
[0.1, 0.1, 0.1, 0.4, 0.91, 0.81, 0.84, 0, 0.1], # channel 1
[0.81, 0.79, 0.85, 0.1, 0.2, 0.61, 0.91, 0, 1], # channel 2
[0.3, 0.1, 0.24, 0.87, 0.62, 1, 0, 1, 1], # channel 3
])
m = binary_mask(arr)
for channel in m:
c = channel.nonzero()[0]
a = (np.where(np.diff(c) != 1)[0]).tolist()
a.insert(0,0)
b = []
for i, x in enumerate(a):
if i == len(a)-1 and i > 0:
b.append([c[x+1], c[-1]])
elif i == len(a)-1 and i == 0:
b.append([c[x], c[-1]])
elif i == 0:
b.append([c[x], c[a[i+1]]])
else:
b.append([c[x+1], c[a[i+1]]])
print('c = ', c)
print('a = ', a)
print('b = ', b)
该程序输出:
c = [4 5 6]
a = [0]
b = [[4, 6]]
c = [0 1 2 5 6 8]
a = [0, 2, 4]
b = [[0, 2], [5, 6], [8, 8]]
c = [3 4 5 7 8]
a = [0, 2]
b = [[3, 5], [7, 8]]
答案 3 :(得分:0)
我想必须有一种更好的方法来按其元素之间的条件对数组进行切片,但我找不到它。
到目前为止,我发现这是一种解决方案,可以按连续元素切片并返回极限值:
import numpy as np
def slice_consecutives(ary):
pass
res=[]
tmp = [ary[0]]
for idx, x in np.ndenumerate(ary[1:]):
if x - ary[idx[0]] > 1 or idx[0] + 2 == len(ary):
if tmp[0] != tmp[-1]: res.append([tmp[0], tmp[-1]])
tmp = []
tmp.append(x)
if ary[-1] - res[-1][-1] == 1: res[-1][-1] = ary[-1]
return res
ary = np.array([0, 2, 3, 5, 6, 7, 8, 11, 12, 13, 14])
print(slice_consecutives(ary))
# => [[2, 3], [5, 8], [11, 14]]
arry = np.array([4,5,6])
print(slice_consecutives(arry))
#=> [[4, 6]]