Eiyrioü von Kauyf
Existe esto ¿Cómo se divide una lista en partes de tamaño uniforme? para dividir una matriz en fragmentos. ¿Hay alguna forma de hacer esto de manera más eficiente para matrices gigantes que usan Numpy?
Prashant Kumar
Probar numpy.array_split
.
De la documentación:
>>> x = np.arange(8.0)
>>> np.array_split(x, 3)
[array([ 0., 1., 2.]), array([ 3., 4., 5.]), array([ 6., 7.])]
Idéntico a numpy.split
pero no generará una excepción si los grupos no tienen la misma longitud.
Si el número de fragmentos> len (matriz), obtiene matrices en blanco anidadas dentro, para abordar eso, si su matriz dividida se guarda en a
entonces puede eliminar matrices vacías de la siguiente manera:
[x for x in a if x.size > 0]
Solo guárdalo de nuevo en a
si lo desea.
-
¿Cómo puedes eliminar las listas vacías?
– Eiyrioü von Kauyf
18/01/2013 a las 20:42
-
¿Puedes dar un pequeño ejemplo?
– Prashant Kumar
28 de enero de 2013 a las 22:48
-
si # chunks > len(matriz) obtiene matrices en blanco anidadas dentro.
– Eiyrioü von Kauyf
29 de enero de 2013 a las 7:50
-
sí, eso era lo que estaba usando … pero de todos modos, ¿hacer eso con numpy? Las listas de comprensión en python son lentas.
– Eiyrioü von Kauyf
29 de enero de 2013 a las 18:45
-
@EiyrioüvonKauyf, para hacerlo con numpy, simplemente limite la cantidad de elementos a la longitud de la matriz:
np.array_split(x, min(len(x), 3))
donde 3 es el número predeterminado de grupos que desea.– David Kaftan
8 mayo 2021 a las 14:50
tzelleké
Solo algunos ejemplos sobre el uso de array_split
, split
, hsplit
y vsplit
:
n [9]: a = np.random.randint(0,10,[4,4])
In [10]: a
Out[10]:
array([[2, 2, 7, 1],
[5, 0, 3, 1],
[2, 9, 8, 8],
[5, 7, 7, 6]])
Algunos ejemplos sobre el uso array_split
:
Si proporciona una matriz o una lista como segundo argumento, básicamente proporciona los índices (antes) que ‘cortar’
# split rows into 0|1 2|3
In [4]: np.array_split(a, [1,3])
Out[4]:
[array([[2, 2, 7, 1]]),
array([[5, 0, 3, 1],
[2, 9, 8, 8]]),
array([[5, 7, 7, 6]])]
# split columns into 0| 1 2 3
In [5]: np.array_split(a, [1], axis=1)
Out[5]:
[array([[2],
[5],
[2],
[5]]),
array([[2, 7, 1],
[0, 3, 1],
[9, 8, 8],
[7, 7, 6]])]
Un entero como segundo argumento. especifica el número de igual trozos:
In [6]: np.array_split(a, 2, axis=1)
Out[6]:
[array([[2, 2],
[5, 0],
[2, 9],
[5, 7]]),
array([[7, 1],
[3, 1],
[8, 8],
[7, 6]])]
split
funciona igual pero genera una excepción si no es posible una división equitativa
Además de array_split
puedes usar atajos vsplit
y hsplit
.
vsplit
y hsplit
son bastante autoexplicativos:
In [11]: np.vsplit(a, 2)
Out[11]:
[array([[2, 2, 7, 1],
[5, 0, 3, 1]]),
array([[2, 9, 8, 8],
[5, 7, 7, 6]])]
In [12]: np.hsplit(a, 2)
Out[12]:
[array([[2, 2],
[5, 0],
[2, 9],
[5, 7]]),
array([[7, 1],
[3, 1],
[8, 8],
[7, 6]])]
-
mi problema con esto es que si chunks > len(array) entonces obtienes matrices anidadas en blanco… ¿cómo te deshaces de eso?
– Eiyrioü von Kauyf
29 de enero de 2013 a las 7:48
-
Buenos ejemplos, gracias. En tus
np.array_split(a, [1], axis=1)
ejemplo, ¿sabe cómo evitar que la primera matriz tenga todos los elementos anidados?– timgeb
4 de enero de 2016 a las 8:11
creo que estas buscando numpy.split
o posiblemente numpy.array_split
si el número de secciones no necesita dividir el tamaño de la matriz correctamente.
-
misma pregunta que le hice a Prashant. ¿Cómo puede deshacerse de las matrices numpy vacías?
– Eiyrioü von Kauyf
18 de enero de 2013 a las 20:44
No es exactamente una respuesta, sino un comentario largo con un buen formato de código para las otras respuestas (correctas). Si intenta lo siguiente, verá que lo que obtiene son vistas de la matriz original, no copias, y ese no fue el caso de la respuesta aceptada en la pregunta que vincula. ¡Tenga en cuenta los posibles efectos secundarios!
>>> x = np.arange(9.0)
>>> a,b,c = np.split(x, 3)
>>> a
array([ 0., 1., 2.])
>>> a[1] = 8
>>> a
array([ 0., 8., 2.])
>>> x
array([ 0., 8., 2., 3., 4., 5., 6., 7., 8.])
>>> def chunks(l, n):
... """ Yield successive n-sized chunks from l.
... """
... for i in xrange(0, len(l), n):
... yield l[i:i+n]
...
>>> l = range(9)
>>> a,b,c = chunks(l, 3)
>>> a
[0, 1, 2]
>>> a[1] = 8
>>> a
[0, 8, 2]
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8]
¿Qué tal esto? Aquí divide la matriz usando la longitud que desea tener.
a = np.random.randint(0,10,[4,4])
a
Out[27]:
array([[1, 5, 8, 7],
[3, 2, 4, 0],
[7, 7, 6, 2],
[7, 4, 3, 0]])
a[0:2,:]
Out[28]:
array([[1, 5, 8, 7],
[3, 2, 4, 0]])
a[2:4,:]
Out[29]:
array([[7, 7, 6, 2],
[7, 4, 3, 0]])
Esto se puede lograr usando as_strided
de numpy. Le di un giro a la respuesta asumiendo que si el tamaño del fragmento no es un factor del número total de filas, entonces el resto de las filas en el último lote se llenarán con ceros.
from numpy.lib.stride_tricks import as_strided
def batch_data(test, chunk_count):
m,n = test.shape
S = test.itemsize
if not chunk_count:
chunk_count = 1
batch_size = m//chunk_count
# Batches which can be covered fully
test_batches = as_strided(test, shape=(chunk_count, batch_size, n), strides=(batch_size*n*S,n*S,S)).copy()
covered = chunk_count*batch_size
if covered < m:
rest = test[covered:,:]
rm, rn = rest.shape
mismatch = batch_size - rm
last_batch = np.vstack((rest,np.zeros((mismatch,rn)))).reshape(1,-1,n)
return np.vstack((test_batches,last_batch))
return test_batches
Esto se basa en mi respuesta https://stackoverflow.com/a/68238815/5462372.
Defina eficiente. Proporcione algunos datos de muestra, su método actual, qué tan rápido es y qué tan rápido necesita que sea.
– Prashant Kumar
31 de diciembre de 2013 a las 18:19
¿Se supone que debemos interpretar la entrada a esta pregunta como una matriz nativa de Pythono un numpy ndarray? La primera oración parece implicar lo primero. La segunda oración implica que está pidiendo una comparación entre el primero y el segundo. Solo bidimensional, presumiblemente. Y cuando decimos “eficientemente… para arreglos gigantes”, ¿estamos más preocupados por la escalabilidad para N asintóticamente grande, sin importar si es más lento para N pequeño?
– smci
9 de noviembre de 2020 a las 23:24