如何使用不等长度的项对矩阵中的值进行分组

时间:2017-07-06 16:16:43

标签: python arrays numpy grouping

假设我有一个简单的数组:

a = np.arange(3)

具有相同长度的索引数组:

I = np.array([0, 0, 1])

我现在想根据索引对值进行分组。 我如何将第一个数组的元素分组以产生下面的结果?

np.array([[0, 1], [2], dtype=object)

以下是我的尝试:

a = np.arange(3)
I = np.array([0, 0, 1])
out = np.empty(2, dtype=object)
out.fill([])

aslists = np.vectorize(lambda x: [x], otypes=['object'])

out[I] += aslists(a)

但是,这种方法不会连接列表,而只维护每个索引的最后一个值:

array([[1], [2]], dtype=object)

或者,对于二维案例:

a = np.random.rand(100)
I = (np.random.random(100) * 5 //1).astype(int)
J = (np.random.random(100) * 5 //1).astype(int)

out = np.empty((5, 5), dtype=object)
out.fill([])

如何根据两个索引数组将项目从a追加到出?

1 个答案:

答案 0 :(得分:1)

1D案例

假设I被排序,对于数组列表作为输出 -

idx = np.unique(I, return_index=True)[1]
out = np.split(a,idx)[1:]

另一个slicingidx分割a -

out = np.split(a, np.flatnonzero(I[1:] != I[:-1])+1)

获取列表数组作为输出 -

np.array([i.tolist() for i in out])

示例运行 -

In [84]: a = np.arange(3)

In [85]: I = np.array([0, 0, 1])

In [86]: out = np.split(a, np.flatnonzero(I[1:] != I[:-1])+1)

In [87]: out
Out[87]: [array([0, 1]), array([2])]

In [88]: np.array([i.tolist() for i in out])
Out[88]: array([[0, 1], [2]], dtype=object)

2D案例

对于2D填充2D数组的情况,其中的分组由两个数组IJ中的索引组成,表示组所在的行和列被分配,我们可以做这样的事情 -

ncols = 5
lidx = I*ncols+J
sidx = lidx.argsort() # Use kind='mergesort' to keep order
lidx_sorted = lidx[sidx]
unq_idx, split_idx = np.unique(lidx_sorted, return_index=True)
out.flat[unq_idx] = np.split(a[sidx], split_idx)[1:]