Enregistrer dans un fichier un tableau ou un datagramme avec d'autres informations
le logiciel statistique Stata permet de sauvegarder des extraits de texte dans un ensemble de données. Ceci est accompli en utilisant notes
et/ou characteristics
.
c'est une caractéristique de grande valeur pour moi car il me permet de sauvegarder une variété d'informations, allant de rappels et de listes de choses à faire à des informations sur la façon dont j'ai généré les données, ou même ce que la méthode d'estimation pour une variable particulière était.
j'essaie maintenant de trouver une fonctionnalité similaire en Python 3.6. Jusqu'à présent, j'ai regardé en ligne et consulté un certain nombre de messages, qui ne traitent toutefois pas exactement ce que je veux faire.
quelques postes de référence:
-
la meilleure façon de préserver les tableaux numpy sur le disque
-
Quelle est la différence entre enregistrer une base de données pandas à pickle et à csv?
-
Comment puis-je visualiser le contenu d'un objet de données dans un fichier npz?
pour un petit NumPy
tableau, j'ai conclu qu'une combinaison de la fonction numpy.savez()
et un dictionary
peut stocker correctement toutes les informations pertinentes dans un seul fichier.
par exemple:
a = np.array([[2,4],[6,8],[10,12]])
d = {"first": 1, "second": "two", "third": 3}
np.savez(whatever_name.npz, a=a, d=d)
data = np.load(whatever_name.npz)
arr = data['a']
dic = data['d'].tolist()
cependant, la question demeure:
y a-t-il de meilleures façons d'incorporer potentiellement d'autres éléments d'information dans un fichier contenant un "tableau 151930920" ou un (grand) Pandas
DataFrame
?
je suis particulièrement intéressé par le particulier pros et cons de toutes les suggestions que vous pourriez avoir avec des exemples. Le moins de dépendances, le mieux.
6 réponses
il y a plusieurs options. Je ne parlerai que de HDF5, car j'ai déjà utilisé ce format.
avantages : Portable (peut être lu en dehors de Python), compression native, capacités hors de la mémoire, prise en charge des métadonnées.
inconvénients : confiance dans une seule API de bas niveau C, possibilité de corruption de données en tant que Fichier unique, la suppression de données ne réduit pas automatiquement la taille.
d'après mon expérience, pour la performance et la portabilité, éviter pyTables
/ HDFStore
pour stocker des données numériques. Vous pouvez utiliser l'interface intuitive fournie par h5py
.
stocker un réseau
import h5py, numpy as np
arr = np.random.randint(0, 10, (1000, 1000))
f = h5py.File('file.h5', 'w', libver='latest') # use 'latest' for performance
dset = f.create_dataset('array', shape=(1000, 1000), data=arr, chunks=(100, 100)
compression='gzip', compression_opts=9)
Compression & chunking
il y a de nombreux choix de compression, par exemple blosc
et lzf
sont de bons choix pour la compression et la performance de décompression respectivement. Note: gzip
est natif; les autres filtres de compression ne peuvent pas être envoyés par défaut avec votre installation HDF5.
Chunking est une autre option qui, lorsqu'elle est alignée avec la façon dont vous lisez les données hors de la mémoire, peut améliorer considérablement les performances.
ajouter quelques attributs
dset.attrs['Description'] = 'Some text snippet'
dset.attrs['RowIndexArray'] = np.arange(1000)
Stocker un dictionnaire
for k, v in d.items():
f.create_dataset('dictgroup/'+str(k), data=v)
accès hors mémoire
dictionary = f['dictgroup']
res = dictionary['my_key']
il n'y a pas de substitut à la lecture de la h5py
documentation , qui expose la plupart des API C, mais vous devriez voir à partir de ce qui précède, il ya une quantité importante de flexibilité.
je suis d'accord avec JPP que le stockage hdf5 est une bonne option ici. La différence entre sa solution et la mienne est que la mienne utilise des bases de données Pandas au lieu de tableaux vides. Je préfère le dataframe car il permet des types mixtes, l'indexation multi-niveaux (même l'indexation datetime, ce qui est très important pour mon travail), et l'étiquetage de Colonne, Ce qui m'aide à me rappeler comment différents ensembles de données sont organisés. En outre, Pandas fournit un grand nombre de fonctionnalités intégrées (un peu comme numpy). Un autre avantage de l'utilisation de Les Pandas c'est qu'il a une hdf créateur (i.e. pour les pandas.DataFrame.to_hdf), qui je trouve pratique
lors du stockage de la dataframe à h5 vous avez l'option de stocker un dictionnaire de métadonnées aussi bien, qui peut être vos notes à vous-même, ou des métadonnées réelles qui n'ont pas besoin d'être stockées dans la dataframe (Je l'utilise aussi pour définir des drapeaux, par exemple {'is_agl': True, 'scale_factor': 100, 'already_corrected': False, etc.}. À cet égard, il n'y a pas de différence entre l'utilisation d'un tableau numpy et un dataframe. Pour la solution complète voir ma question originale et la solution ici.
Un moyen pratique pourrait être d'intégrer des méta-données directement à l'intérieur du tableau Numpy. L'avantage est que, comme vous le souhaitez, il n'y a pas de dépendance supplémentaire et c'est très simple à utiliser dans le code. Cependant, cela ne répond pas entièrement à votre question, parce que vous avez encore besoin d'un mécanisme pour enregistrer les données, et je recommande d'utiliser jpp solution en utilisant HDF5.
pour inclure des métadonnées dans un ndarray
, il y a un exemple dans documentation .
Vous devez essentiellement sous-classe un ndarray
et Ajouter un champ info
ou metadata
ou autre.
Il donnerait (code à partir du lien ci-dessus)
import numpy as np
class ArrayWithInfo(np.ndarray):
def __new__(cls, input_array, info=None):
# Input array is an already formed ndarray instance
# We first cast to be our class type
obj = np.asarray(input_array).view(cls)
# add the new attribute to the created instance
obj.info = info
# Finally, we must return the newly created object:
return obj
def __array_finalize__(self, obj):
# see InfoArray.__array_finalize__ for comments
if obj is None: return
self.info = getattr(obj, 'info', None)
pour sauvegarder les données via numpy
, vous devez surcharger la fonction write
ou utiliser une autre solution.
la réponse de jpp est assez complète, je voulais juste mentionner que dès pandas V22 parquet est très pratique et option rapide avec presque aucun inconvénients vs csv (Accepter peut-être la pause-café).
au moment de l'écriture, vous aurez besoin de aussi
pip install pyarrow
en termes d'ajout d'informations, vous avez le métadonnées jointes aux données
import pyarrow as pa
import pyarrow.parquet as pq
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.normal(size=(1000, 10)))
tab = pa.Table.from_pandas(df)
tab = tab.replace_schema_metadata({'here' : 'it is'})
pq.write_table(tab, 'where_is_it.parq')
pq.read_table('where_is_it.parq')
qui donnent alors une table
Pyarrow table
0: double
1: double
2: double
3: double
4: double
5: double
6: double
7: double
8: double
9: double
__index_level_0__: int64
metadata
--------
{b'here': b'it is'}
pour retourner à pandas:
tab.to_pandas()
c'est une question intéressante, bien que très ouverte je pense.
Extraits De Texte
Pour les extraits de texte qui ont des notes littérales (comme dans, pas de code et pas de données), Je ne sais vraiment pas ce qu'est votre cas d'utilisation, mais je ne vois pas pourquoi je dévierais de l'utilisation de l'habituel with open() as f: ...
petites collections de diverses pièces de données
Bien sûr, votre npz
works. En fait ce que vous faites est très similaire à la création d'un dictionnaire avec tout ce que vous voulez enregistrer et conserver le dictionnaire.
Voir ici pour une discussion des différences entre cornichon et npz (mais surtout, npz est optimisé pour les tableaux numpy).
personnellement, je dirais que si vous ne stockez pas de tableaux vides j'utiliserais pickle, et même implémenter une classe rapide MyNotes
qui est essentiellement un dictionnaire d'enregistrer des choses, avec quelques fonctionnalités supplémentaires que vous désirez.
Collection de grands objets
Pour de très gros np.tableaux ou images de données que j'ai utilisés avant le format HDF5. La bonne chose est qu'il est déjà intégré dans les pandas et vous pouvez directement df.to_hdf5()
. Il n'a pas besoin sous pytables
- l'installation devrait être assez indolore avec pip ou conda - mais en utilisant pytables directement peut être une douleur beaucoup plus grande.
encore une fois, cette idée est très similaire: vous créez un HDFStore, qui est à peu près un grand dictionnaire dans lequel vous pouvez stocker (presque n'importe quel) des objets. L'avantage est que le format utilise l'espace d'une manière plus intelligente en tirant profit de la répétition de valeurs similaires. Quand je l'utilisais pour stocker des images de ~2 Go, il était capable de le réduire d'un ordre de grandeur presque complet (~250 Mo).
une dernière joueur: feather
Feather
est un projet créé par Wes McKinney et Hadley Wickham sur le dessus du cadre Apache Arrow, pour persister les données dans un format binaire qui est agnostique langage (et donc vous pouvez lire à partir de R et Python). Cependant, il est encore en cours de développement, et la dernière fois que j'ai vérifié qu'ils n'ont pas encouragé à l'utiliser pour le stockage à long terme (puisque la spécification peut changer dans les versions futures), plutôt que il suffit de l'utiliser pour la communication entre R et Python.
ils viennent tous les deux de lancer Ursalabs , littéralement il y a quelques semaines, qui vont continuer à développer cette initiative et d'autres similaires.
vous avez déclaré comme les raisons de cette question:
... il me permet de sauver un une variété d'informations, allant de rappels et de listes de choses à faire, d'informations sur comment j'ai généré les données, ou même ce que l' la méthode d'estimation pour une variable particulière était .
puis-je suggérer un paradigme différent de celui offert par Stata? Les notes et les caractéristiques semble être très limitée et confiné au texte. Vous devriez plutôt utiliser Jupyter Notebook pour vos projets de recherche et d'analyse de données. Il fournit un environnement aussi riche pour documenter votre flux de travail et capturer des détails, des pensées et des idées que vous faites votre analyse et recherche. Il peut facilement être partagé, et c'est de présentation.
Voici une galerie de carnets Jupyter intéressants à travers de nombreuses industries et des disciplines pour mettre en valeur les nombreuses fonctionnalités et utiliser des cas de carnets. Il peut élargir vos horizons au-delà d'essayer de concevoir un moyen d'étiqueter des bribes de texte simples à vos données.