Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

237
Views
cómo realizar la agrupación máxima / media en una matriz 2d usando numpy

Dada una matriz 2D (M x N) y un kernel 2D (K x L), ¿cómo devuelvo una matriz que es el resultado de la agrupación máxima o media usando el kernel dado sobre la imagen?

Me gustaría usar numpy si es posible.

Nota: M, N, K, L pueden ser pares o impares y no es necesario que sean perfectamente divisibles entre sí, por ejemplo: matriz 7x5 y núcleo 2x2.

por ejemplo, de agrupación máxima:

 matrix: array([[ 20, 200, -5, 23], [ -13, 134, 119, 100], [ 120, 32, 49, 25], [-120, 12, 09, 23]]) kernel: 2 x 2 soln: array([[ 200, 119], [ 120, 49]])
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Podrías usar scikit-image block_reduce :

 import numpy as np import skimage.measure a = np.array([ [ 20, 200, -5, 23], [ -13, 134, 119, 100], [ 120, 32, 49, 25], [-120, 12, 9, 23] ]) skimage.measure.block_reduce(a, (2,2), np.max)

Da:

 array([[200, 119], [120, 49]])
over 4 years ago · Santiago Trujillo Report

0

Si el tamaño de la imagen es divisible uniformemente por el tamaño del kernel, puede remodelar la matriz y usar el max o mean como mejor le parezca.

 import numpy as np mat = np.array([[ 20, 200, -5, 23], [ -13, 134, 119, 100], [ 120, 32, 49, 25], [-120, 12, 9, 23]]) M, N = mat.shape K = 2 L = 2 MK = M // K NL = N // L print(mat[:MK*K, :NL*L].reshape(MK, K, NL, L).max(axis=(1, 3))) # [[200, 119], [120, 49]]

Si no tiene un número par de kernels, tendrá que manejar los límites por separado. (Como se señaló en los comentarios, esto da como resultado que se copie la matriz, lo que afectará el rendimiento).

 mat = np.array([[20, 200, -5, 23, 7], [-13, 134, 119, 100, 8], [120, 32, 49, 25, 12], [-120, 12, 9, 23, 15], [-57, 84, 19, 17, 82], ]) # soln # [200, 119, 8] # [120, 49, 15] # [84, 19, 82] M, N = mat.shape K = 2 L = 2 MK = M // K NL = N // L # split the matrix into 'quadrants' Q1 = mat[:MK * K, :NL * L].reshape(MK, K, NL, L).max(axis=(1, 3)) Q2 = mat[MK * K:, :NL * L].reshape(-1, NL, L).max(axis=2) Q3 = mat[:MK * K, NL * L:].reshape(MK, K, -1).max(axis=1) Q4 = mat[MK * K:, NL * L:].max() # compose the individual quadrants into one new matrix soln = np.vstack([np.c_[Q1, Q3], np.c_[Q2, Q4]]) print(soln) # [[200 119 8] # [120 49 15] # [ 84 19 82]]
over 4 years ago · Santiago Trujillo Report

0

En lugar de hacer "cuadrantes" como se muestra en la respuesta de Elliot, podríamos rellenarlo para que sea divisible de manera uniforme y luego realizar una agrupación máxima o media.

Como la agrupación se usa a menudo en CNN, la matriz de entrada suele ser 3D. Así que hice una función que funciona en matrices 2D o 3D.

 def pooling(mat,ksize,method='max',pad=False): '''Non-overlapping pooling on 2D or 3D data. <mat>: ndarray, input array to pool. <ksize>: tuple of 2, kernel size in (ky, kx). <method>: str, 'max for max-pooling, 'mean' for mean-pooling. <pad>: bool, pad <mat> or not. If no pad, output has size n//f, n being <mat> size, f being kernel size. if pad, output has size ceil(n/f). Return <result>: pooled matrix. ''' m, n = mat.shape[:2] ky,kx=ksize _ceil=lambda x,y: int(numpy.ceil(x/float(y))) if pad: ny=_ceil(m,ky) nx=_ceil(n,kx) size=(ny*ky, nx*kx)+mat.shape[2:] mat_pad=numpy.full(size,numpy.nan) mat_pad[:m,:n,...]=mat else: ny=m//ky nx=n//kx mat_pad=mat[:ny*ky, :nx*kx, ...] new_shape=(ny,ky,nx,kx)+mat.shape[2:] if method=='max': result=numpy.nanmax(mat_pad.reshape(new_shape),axis=(1,3)) else: result=numpy.nanmean(mat_pad.reshape(new_shape),axis=(1,3)) return result

A veces, es posible que desee realizar una agrupación superpuesta, a un ritmo que no es igual al tamaño del núcleo. Aquí hay una función que hace eso, con o sin relleno:

 def asStride(arr,sub_shape,stride): '''Get a strided sub-matrices view of an ndarray. See also skimage.util.shape.view_as_windows() ''' s0,s1=arr.strides[:2] m1,n1=arr.shape[:2] m2,n2=sub_shape view_shape=(1+(m1-m2)//stride[0],1+(n1-n2)//stride[1],m2,n2)+arr.shape[2:] strides=(stride[0]*s0,stride[1]*s1,s0,s1)+arr.strides[2:] subs=numpy.lib.stride_tricks.as_strided(arr,view_shape,strides=strides) return subs def poolingOverlap(mat,ksize,stride=None,method='max',pad=False): '''Overlapping pooling on 2D or 3D data. <mat>: ndarray, input array to pool. <ksize>: tuple of 2, kernel size in (ky, kx). <stride>: tuple of 2 or None, stride of pooling window. If None, same as <ksize> (non-overlapping pooling). <method>: str, 'max for max-pooling, 'mean' for mean-pooling. <pad>: bool, pad <mat> or not. If no pad, output has size (nf)//s+1, n being <mat> size, f being kernel size, s stride. if pad, output has size ceil(n/s). Return <result>: pooled matrix. ''' m, n = mat.shape[:2] ky,kx=ksize if stride is None: stride=(ky,kx) sy,sx=stride _ceil=lambda x,y: int(numpy.ceil(x/float(y))) if pad: ny=_ceil(m,sy) nx=_ceil(n,sx) size=((ny-1)*sy+ky, (nx-1)*sx+kx) + mat.shape[2:] mat_pad=numpy.full(size,numpy.nan) mat_pad[:m,:n,...]=mat else: mat_pad=mat[:(m-ky)//sy*sy+ky, :(n-kx)//sx*sx+kx, ...] view=asStride(mat_pad,ksize,stride) if method=='max': result=numpy.nanmax(view,axis=(2,3)) else: result=numpy.nanmean(view,axis=(2,3)) return result
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!