Python 按子数组索引列表拆分数组
假设我有一个数组Python 按子数组索引列表拆分数组,python,split,sub-array,Python,Split,Sub Array,假设我有一个数组X和一个索引列表k_ar,最大值是k-1 我想做的基本上是拆分X,这样X[I]进入子数组k_ar[I]。执行此操作的O(n)方法如下: X = [5, 1, 3, 2, 2, 1] k_ar = [0, 1, 0, 1, 2] K = max(k_ar) + 1 sub_X = [[] for k in range(K)] for k, x in zip(k_ar, X): sub_X[k].append(x) 虽然这是做这类事情的理想算法,但我想知道Numpy
X
和一个索引列表k_ar
,最大值是k-1
我想做的基本上是拆分X
,这样X[I]
进入子数组k_ar[I]
。执行此操作的O(n)
方法如下:
X = [5, 1, 3, 2, 2, 1]
k_ar = [0, 1, 0, 1, 2]
K = max(k_ar) + 1
sub_X = [[] for k in range(K)]
for k, x in zip(k_ar, X):
sub_X[k].append(x)
虽然这是做这类事情的理想算法,但我想知道Numpy、Scipy或任何其他库是否有更快的方法。例如,我可以这样做,但它是O(nK)
而不是O(n)
,因此对于大型K
,它是次优的,尽管在n
中非常快:
import numpy as np
X = np.ndarray([5, 1, 3, 2, 2, 1], dtype=np.int8)
k_ar = np.ndarray([0, 1, 1, 0, 1, 2], dtype=np.int8)
K = max(k_ar)
sub_X = np.empty(K, dtype=np.ndarray)
for k in range(K):
sub_X[k] = X[k_ar == k]
那么,还有没有一种方法可以在不使用Numba、Cython或PyPy的情况下加快速度?您的算法是O(n):最大迭代需要n个步骤,列表创建的迭代有n个步骤,放置的迭代也有n个步骤
此外,我不确定是否有任何理由在迭代期间保持原始列表和索引不变,这意味着您可以通过弹出将内存保持在n个元素而不是2n个元素
最终代码-O(n)内存,O(n)CPU:
您的算法是O(n):最大值的迭代需要n个步骤,列表创建的迭代有n个步骤,放置的迭代也有n个步骤
此外,我不确定是否有任何理由在迭代期间保持原始列表和索引不变,这意味着您可以通过弹出将内存保持在n个元素而不是2n个元素
最终代码-O(n)内存,O(n)CPU:
第一个例子看起来不错。第二个示例需要
np.array
,顺便说一句,第一个示例看起来不错。对于第二个示例,您需要np.array
,顺便说一句,当k
为常数时,O(n)=O(kn)
不是吗?也就是说,O(3n)=O(n)=O(2n)
?不完全确定,但它是内存的一半,所以为什么不:-)是的,当然,我只是指出(我想)这就是大O符号的工作原理:)等等,O(n)=O(kn)
当k
是常数时,不是?也就是说,O(3n)=O(n)=O(2n)
?不完全确定,但它是内存的一半,所以为什么不:-)是的,当然,我只是指出(我认为)这就是大O符号的工作原理:)
X = [5, 1, 3, 2, 2, 1]
k_ar = [0, 1, 0, 1, 2]
sub_x = []
while X:
k = k_ar.pop()
try:
sub_x[k].append(X.pop())
except IndexError:
sub_x.extend([] for i in range(len(sub_x), k+1))
sub_x[k].append(X.pop())