Estoy tratando de concatenar los valores si tienen los mismos índices. Estoy trabajando con forma rectangular, así que sé:
Básicamente,
Desde:
a = array([
[ 1, 5],
[ 1, 7],
[ 2, 8],
[ 2, 10],
[ 2, 22],
[ 3, 55],
[ 3, 77]])
A:
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]])
He intentado convertirlo en una lista y revisar cada valor usando un bucle for, pero lleva una cantidad considerable de tiempo.
También intenté ordenar la matriz np.sort(a, axis=0)
y tomar cada dos filas, pero como puede haber más de dos de los índices, falla.
Soy nuevo en numpy, así que no sé qué más probar.
Cualquier sugerencia sería útil, gracias.
Editar: su comportamiento es como un diccionario donde las claves son un [0] y los valores son un [1:]
Si hay más de 2 valores, solo conservo el mínimo y el máximo.
Enfoque # 1
Una forma NumPy vectorizada sería:
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]]
Ejecución de muestra -
# 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]])
Enfoque # 2
Podemos mejorar la memoria para ordenar solo la primera fila sidx
, así:
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]]
Esto podría ser mejor con muchas entradas por grupo.
Alternativa n. ° 1: sidx
utilice el mapeo de índice lineal
Para números int positivos, podemos asumir que están en la 2D
cuadrícula y, por lo tanto, obtener equivalentes de índice lineal para cada fila. Por lo tanto, saltaremos lexsort
y nos pondremos sidx
así -
sidx = (a[:,0]*(a[:,1].max()+1) + a[:,1]).argsort()
El resto del código después de la obtención sidx
permanece igual en los dos enfoques publicados anteriormente.
Alternativa n. ° 2: empezar a sidx
usarviews
Podríamos usar views
para obtener sidx
y, por lo tanto lexsort
, saltar de nuevo , así:
# 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()
Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.
En caso de infracción, por favor [email protected] Eliminar
Déjame decir algunas palabras