2016-04-21 2 views
1

Existe-t-il une méthode pour enregistrer un tableau memmap numpy dans un fichier .npy? Apparemment, il existe une méthode pour charger un tel tableau à partir d'un fichier .npy comme suitVider nummap memmap vers le fichier npy

data = numpy.load("input.npy", mmap_mode='r') 

mais le rinçage du fichier ne correspond pas à le stocker dans un format .npy.

Si le rinçage est la seule solution, existe-t-il un moyen de déduire la forme de la matrice stockée? Je préférerais avoir une forme dynamique qui est automatiquement stockée et récupérée (éventuellement en tant que memmap) dans un autre script.

J'ai cherché sur divers endroits à ce sujet mais je n'ai trouvé aucun résultat. Je moyen de stocker dans .npy que je fais est maintenant

numpy.save(output.filename, output.copy()) 

qui contrecarre l'idée d'utiliser memmap mais conserve la forme.

REMARQUE: Je connais les fonctions hdf5 et h5py, mais je me demandais s'il existait une solution purement numérique.

Répondre

3

Y at-il un moyen de déduire la forme de la matrice stockée?

No. En ce qui concerne np.memmap le fichier est juste un tampon - il stocke le contenu du tableau, mais pas les dimensions, dtype etc. Il n'y a aucun moyen d'inférer cette information sauf si elle est en quelque sorte contenue dans le tableau lui-même. Si vous avez déjà créé un np.memmap soutenu par un fichier binaire simple, vous devrez écrire son contenu dans un nouveau fichier .npy sur le disque.

Vous pouvez éviter de générer une copie en mémoire en ouvrant le nouveau fichier .npy comme un autre tableau mappé en mémoire à l'aide numpy.lib.format.open_memmap:

import numpy as np 
from numpy.lib.format import open_memmap 

# a 10GB memory-mapped array 
x = np.memmap('/tmp/x.mm', mode='w+', dtype=np.ubyte, shape=(int(1E10),)) 

# create a memory-mapped .npy file with the same dimensions and dtype 
y = open_memmap('/tmp/y.npy', mode='w+', dtype=x.dtype, shape=x.shape) 

# copy the array contents 
y[:] = x[:] 
+1

Cette fonction 'open_memmap' est une conclusion - je voulais juste la façon de commencer un tableau' .npy' soutenu, mais en ajoutant une option enregistrer un tableau qui pourrait être coincé dans un fichier binaire est encore mieux. – pevogam

1

Avertissement: Les travaux suivants avec la version 1.11.2 numpy (et plus tard, je suppose), mais une version antérieure j'ai essayé (1.8.2) a donné une erreur.

Un tableau enregistré avec np.save est essentiellement un memmap avec un en-tête spécifiant dtype, shape et l'ordre des éléments. Vous pouvez en lire plus à ce sujet dans le numpy documentation. Lorsque vous créez votre np.memmap, vous pouvez réserver de l'espace pour cet en-tête avec le paramètre offset.

Remarque: La documentation indique que la longueur d'en-tête doit être un multiple de 16:

Supposons que vous réservez 5 * 16 = 80 octets pour l'en-tête (voir plus bas):

import numpy as np 
x = np.memmap('/tmp/x.npy', mode='w+', dtype=np.ubyte, shape=(int(1E10),), offset=80) 

Puis, quand vous avez terminé la manipulation de la memmap, vous créez et écrivez l'en-tête, à l'aide np.lib.format:

header = np.lib.format.header_data_from_array_1_0(x) 

with open('/tmp/x.npy', 'r+b') as f: 
    np.lib.format.write_array_header_1_0(f, header) 

Notez que ce écrit l'en-tête depuis le début du fichier memmap, donc si len(header) > 80, il écraserez une partie des données , et votre fichier sera n être lisible.L'en-tête est une chaîne magique de longueur fixe, deux octets de version, deux octets spécifiant la longueur de l'en-tête et une représentation sous forme de chaîne d'un dictionnaire spécifiant 'shape', 'descr' et 'order'. Si vous connaissez la forme et le type (descr) de votre tableau, vous pouvez facilement calculer la longueur de l'en-tête (je l'ai fixé à 80 ci-dessus, par souci de simplicité).

Après avoir écrit l'en-tête, vous pouvez charger les données à l'aide np.load:

y = np.load('/tmp/x.npy')