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:

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.

29
demandé sur Pearly Spencer 2018-04-09 22:21:31

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é.

14
répondu jpp 2018-04-26 16:29:02

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.

4
répondu tnknepp 2018-04-25 12:08:51

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.

1
répondu Christian 2018-04-24 09:46:21

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é).

lire parquet

Ecrire parquet

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()
1
répondu Darren Brien 2018-04-25 18:44:56

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.

-1
répondu WillMonge 2018-04-21 02:47:10

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.

-1
répondu floydn 2018-04-24 17:37:14