[PYTHON] Correction du problème selon lequel la mémoire du tableau numpy ne tient pas dans numpy.memmap

exemple

Je veux écrire et lire un tableau numpy np.random.rand (100000, 99999) .astype (dtype = 'float32') qui ne tient pas en mémoire dans un seul fichier. Je veux faire quelque chose comme ça:

import numpy as np

arr = np.random.rand(100000, 99999).astype(dtype='float32')
np.save('np_save.npy', arr)

Mais ʻarr` fait environ 40 Go, donc il n'entre pas en mémoire et est tué:

>>> import numpy as np
>>> arr = np.random.rand(100000, 99999).astype(dtype='float32')
Killed: 9

Générons et ajoutons dans une boucle au lieu de générer 100000 en haut. Parcourons une boucle de génération de 100 lignes 1000 fois.

La méthode d'ajout à la liste, np.vstack et np.save fonctionne bien lors de l'entrée en mémoire, mais cela étend également 40 Go de mémoire, donc il est tué:

>>> arr_list = []
>>> for i in range(1000):
...     arr = np.random.rand(100, 99999).astype(dtype='float32')
...     arr_list.append(arr)
...

>>> np.save('np_save.npy', np.vstack(arr_list))
Killed: 9

Solution

Vous pouvez écrire dans un fichier avec np.memmap sans consommer de mémoire. Tout d'abord, spécifiez la forme et générez une carte mémoire. Écrit des données dans la tranche spécifiée dans une boucle.

import numpy as np
fp = np.memmap('np_save.dat', dtype='float32', mode='w+', shape=(100000, 99999))
del fp
for i in range(1000):
    arr = np.random.rand(100, 99999).astype(dtype='float32')
    fp = np.memmap('np_save.dat', dtype='float32', mode='r+', shape=(100000,99999))
    fp[i*100:(i+1)*100] = arr
    del fp

L'utilisation de la mémoire est supprimée comme ceci: Figure_1.png

L'avantage de np.memmap est qu'il peut être lu instantanément et que les segments de données sur le disque peuvent être lus par tranches. Seules les données à utiliser peuvent être développées en mémoire.

>>> import numpy as np
>>> newfp = np.memmap('np_save.dat', dtype='float32', mode='r', shape=(100000, 99999))
>>> newfp
memmap([[0.9187665 , 0.7200832 , 0.36402512, ..., 0.88297397, 0.90521574,
         0.80509114],
        [0.56751174, 0.06882019, 0.7239285 , ..., 0.04442023, 0.26091048,
         0.07676199],
        [0.94537544, 0.06935687, 0.13554753, ..., 0.3666087 , 0.6137967 ,
         0.1677396 ],
        ...,
        [0.97691774, 0.08142337, 0.18367094, ..., 0.30060798, 0.5744949 ,
         0.3676454 ],
        [0.13025525, 0.36571756, 0.17128325, ..., 0.8568927 , 0.9460005 ,
         0.61096454],
        [0.22953852, 0.00882731, 0.15313177, ..., 0.90694803, 0.17832297,
         0.45886058]], dtype=float32)
>>> newfp[30:40]
memmap([[0.23530068, 0.64027864, 0.7193347 , ..., 0.0991324 , 0.71703744,
         0.0429478 ],
        [0.7835149 , 0.20407963, 0.23541291, ..., 0.12721954, 0.6010988 ,
         0.8794886 ],
        [0.62712234, 0.76977116, 0.4803686 , ..., 0.24469836, 0.7741827 ,
         0.14326976],
        ...,
        [0.4855294 , 0.15554492, 0.6792018 , ..., 0.23985237, 0.59824246,
         0.88751584],
        [0.80865365, 0.73577726, 0.9209202 , ..., 0.9908406 , 0.66778165,
         0.16570805],
        [0.63171065, 0.48431855, 0.57776374, ..., 0.76027304, 0.930301  ,
         0.20145524]], dtype=float32)
>>> arr = np.array( newfp[30:40])
>>> arr
array([[0.23530068, 0.64027864, 0.7193347 , ..., 0.0991324 , 0.71703744,
        0.0429478 ],
       [0.7835149 , 0.20407963, 0.23541291, ..., 0.12721954, 0.6010988 ,
        0.8794886 ],
       [0.62712234, 0.76977116, 0.4803686 , ..., 0.24469836, 0.7741827 ,
        0.14326976],
       ...,
       [0.4855294 , 0.15554492, 0.6792018 , ..., 0.23985237, 0.59824246,
        0.88751584],
       [0.80865365, 0.73577726, 0.9209202 , ..., 0.9908406 , 0.66778165,
        0.16570805],
       [0.63171065, 0.48431855, 0.57776374, ..., 0.76027304, 0.930301  ,
        0.20145524]], dtype=float32)

Je pense qu'il peut être utilisé pour traiter des données dans l'apprentissage automatique.

Méthode non recommandée

Il existe np.savetxt comme moyen d'ajouter directement à un fichier, mais je ne le recommande pas! C'est très lent et le fichier devient énorme (supérieur à la taille des données d'origine):

with open('np_save.dat','ab') as f:
    for i in range(1000):
        arr = np.random.rand(100, 99999).astype(dtype='float32')
        np.savetxt(f,arr)

Recommended Posts

Correction du problème selon lequel la mémoire du tableau numpy ne tient pas dans numpy.memmap
où de numpy
Tri rapide d'un tableau en Python 3
Inverser le tableau booléen numpy dans tilda
Créez un tableau vide avec Numpy pour ajouter des lignes pour chaque boucle