我有一个1维数组,其中的肠腔中有一个模式。我举一个例子。在数组ALTER FOREIGN FUNCTION app.fn_getphone
(
iduser INT
)
SERVER mssql_svr_cm OPTIONS (TABLE 'dbo.fn_getphone', row_estimate_method
'showplan_all');
中,我有
前4个具有一位数字的小肠,其次4个具有两位数字的小肠,然后下6个具有3位数字的小肠。
(这个单,双,三位数只是为了突出显示模式。实际的数组具有相似值的浮点数。)示例的一维数组看起来像:
arr
现在,一个完整的模式共有4 + 4 + 6 = 14个肠。此模式(或重复单元)重复了数十万次,因此我数组的长度是14的倍数(在上面的示例import numpy as np
arr = np.array([1, 2, 3, 4, 11, 12, 13, 14, 111, 123, 132, 145, 176, 129,
6, 5, 3, 2, 21, 82, 53, 34, 121, 133, 139, 165, 186, 119])
中为14 * 2 = 28)。
问题:
我要提取所有一位数字的小肠(一个重复单元的前4个数字),所有两位数字的小肠 (一个重复单元的后4个数字)和所有三位数的小肠(一个重复单元的后6个数字)。
这样,我想将我的大arr
分成三个一维数组。因此,所需的输出是
arr
我的想法
一种方法可能是将arr1 = array([1, 2, 3, 4, 6, 5, 3, 2])
arr2 = array([11, 12, 13, 14, 21, 82, 53, 34])
arr3 = array([111, 123, 132, 145, 176, 129, 121, 133, 139, 165, 186, 119])
简单地放入2d数组,因为我知道重复的次数(在示例reshape
中== 28/14 = 2),然后使用索引来获取所有第一个4、4和6的块
然后arr
。
concatenate
,然后使用切片将块作为
arr = arr.reshape(2, 14)
但是我有兴趣了解使用某种 masking 和 slicing 而无需先转换为2d的替代高效解决方案数组。
答案 0 :(得分:1)
根据要求使用图案的遮罩(并假设arr长度是遮罩长度的精确倍数):
mask1 = [True]*4 + [False]*10
mask2 = [False]*4 + [True]*4 + [False]*6
mask3 = [False]*8 + [True]*6
然后您可以通过执行以下操作直接获得所需的数组:
n_masks = (len(arr) // len(mask1))
arr1 = arr[mask1 * n_masks]
arr2 = arr[mask2 * n_masks]
arr3 = arr[mask3 * n_masks]
答案 1 :(得分:1)
您可以直接访问索引
import numpy as np
arr = np.array([1, 2, 3, 4, 11, 12, 13, 14, 111, 123, 132, 145, 176, 129,
6, 5, 3, 2, 21, 82, 53, 34, 121, 133, 139, 165, 186, 119])
run_length = 14
repetitions = 2
indices1 = [run_length * i + j for i in range(repetitions) for j in range(4)]
arr1 = arr[indices1]
indices2 = [run_length * i + j for i in range(repetitions) for j in range(4, 8)]
arr2 = arr[indices2]
indices3 = [run_length * i + j for i in range(repetitions) for j in range(8, 14)]
arr3 = arr[indices3]
print(arr1)
print(arr2)
print(arr3)
输出
[1 2 3 4 6 5 3 2]
[11 12 13 14 21 82 53 34]
[111 123 132 145 176 129 121 133 139 165 186 119]
您可以将所有内容放入这样的函数中:
import numpy as np
arr = np.array([1, 2, 3, 4, 11, 12, 13, 14, 111, 123, 132, 145, 176, 129,
6, 5, 3, 2, 21, 82, 53, 34, 121, 133, 139, 165, 186, 119])
def extract(arr, run_length, repetitions, pattern_lengths):
chunks = [0] + np.cumsum(pattern_lengths).tolist()
for start, end in zip(chunks, chunks[1:]):
indices = [run_length * i + j for i in range(repetitions) for j in range(start, end)]
yield arr[indices]
arr1, arr2, arr3 = list(extract(arr, 14, 2, [4, 4, 6]))
print(arr1)
print(arr2)
print(arr3)
答案 2 :(得分:1)
您还可以构建遮罩:
# if you know where your indices are, otherwise use a formula
mask = np.zeros((3, 2, 14), dtype=bool)
mask[0,:, 0:4] = True
mask[1,:, 4:8] = True
mask[2,:, 8:] = True
arr1, arr2, arr3 = (arr[m.flatten()] for m in mask)
print (arr1, arr2, arr3)
答案 3 :(得分:1)
我们可以简单地重塑为2D
(记住重塑会创建一个视图,并且内存开销为零,因此在运行时实际上是空闲的),而col的数量与模式lenth相同(示例中为14)。然后,slice
列出第一个数组输出的前4个条目,接下来的4个用于第二个数组,最后的第8个col用于最后一个数组。
因为我们需要扁平化的输出,所以可以使用.ravel()
来实现。
因此-
In [44]: a2d = arr.reshape(-1,14) # 2d view into arr
...: arr1,arr2,arr3 = a2d[:,:4].ravel(),a2d[:,4:8].ravel(),a2d[:,8:].ravel()
In [45]: arr1
Out[45]: array([1, 2, 3, 4, 6, 5, 3, 2])
In [46]: arr2
Out[46]: array([11, 12, 13, 14, 21, 82, 53, 34])
In [47]: arr3
Out[47]: array([111, 123, 132, 145, 176, 129, 121, 133, 139, 165, 186, 119])
现在,说我们对2D数组输出没问题,然后-
In [48]: arr1,arr2,arr3 = a2d[:,:4],a2d[:,4:8],a2d[:,8:]
In [49]: arr1
Out[49]:
array([[1, 2, 3, 4],
[6, 5, 3, 2]])
In [50]: arr2
Out[50]:
array([[11, 12, 13, 14],
[21, 82, 53, 34]])
In [51]: arr3
Out[51]:
array([[111, 123, 132, 145, 176, 129],
[121, 133, 139, 165, 186, 119]])
那么,为什么要接受这个?因为它是原始输入arr
的视图,因此如前所述,它的内存开销为零,实际上是空闲的-
In [52]: np.shares_memory(arr,arr1)
Out[52]: True
依次类推,其他两个数组。