我正在尝试将值具有相同的索引连接起来。我正在使用矩形,所以我知道:
总会有至少两个相同的索引。
如果有两个以上的索引,我只需要存储最大值和最小值。
基本上,
从:
a = array([
[ 1, 5],
[ 1, 7],
[ 2, 8],
[ 2, 10],
[ 2, 22],
[ 3, 55],
[ 3, 77]])
至:
b = np.array([
[ 1, 5, 7],
[ 2, 8, 22], # [2,8,10,22] but the min is 8 and max is 22
[ 3, 55, 77]])
我试图将其转换为列表,并使用for循环遍历每个值,但是这需要花费大量时间。
我还尝试对数组
np.sort(a, axis=0)
进行排序,并每隔一行走一次,但是由于可以有两个以上的索引,因此失败。我是numpy的新手,所以不知道还能尝试什么。
任何和所有建议都会有所帮助,谢谢。
编辑:其行为类似于字典,其中键为a [0],值为a [1:]
如果有两个以上的值,则仅保留最小值和最大值。
最佳答案
方法1
向量NumPy的方式是-
def agg_minmax(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx]
m = np.r_[True,b[:-1,0]!=b[1:,0],True]
return np.c_[b[m[:-1],:2], b[m[1:],1]]
样品运行-
# Generic case with input not-necessarily sorted by first col
In [35]: a
Out[35]:
array([[ 3, 77],
[ 2, 8],
[ 1, 7],
[ 2, 10],
[ 1, 5],
[ 3, 55],
[ 2, 22]])
In [36]: agg_minmax(a)
Out[36]:
array([[ 1, 5, 7],
[ 2, 8, 22],
[ 3, 55, 77]])
方法#2
我们可以改进内存以按
sidx
仅对第一行进行排序,如下所示-def agg_minmax_v2(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx,0]
m = np.r_[True,b[:-1]!=b[1:],True]
return np.c_[a[sidx[m[:-1]]],a[sidx[m[1:]],1]]
每个组有很多条目可能会更好。
备选方案1:使用线性索引映射获取
sidx
对于正整数值,我们可以假定它们在
2D
网格上,因此可以得到每行的线性索引等效项。因此,我们将像这样跳过lexsort
并获得sidx
-sidx = (a[:,0]*(a[:,1].max()+1) + a[:,1]).argsort()
在两个较早发布的方法中,获取
sidx
后的其余代码保持不变。备选方案2:使用
sidx
获取views
我们可以使用
views
来获取sidx
,因此再次跳过lexsort
,就像这样-# https://stackoverflow.com/a/44999009/ @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
A = view1D(a)
sidx = A.argsort()