Est-il possible d'ajouter des méta-informations / métadonnées à un pandas DataFrame?
Par exemple, le nom de l'instrument utilisé pour mesurer les données, l'instrument responsable, etc.
Une solution de contournement serait de créer une colonne avec ces informations, mais il semble inutile de stocker une seule information dans chaque ligne!
Réponses:
Bien sûr, comme la plupart des objets Python, vous pouvez attacher de nouveaux attributs à un
pandas.DataFrame
:import pandas as pd df = pd.DataFrame([]) df.instrument_name = 'Binky'
Notez toutefois que si vous pouvez attacher des attributs à une trame de données, les opérations effectuées sur le dataframe ( par exemple
groupby
,pivot
,join
ouloc
pour ne citer que quelques - uns) peut retourner une nouvelle trame de données sans les métadonnées ci - joint. Pandas ne dispose pas encore d'une méthode robuste de propagation des métadonnées attachées aux DataFrames .La conservation des métadonnées dans un fichier est possible. Vous pouvez trouver un exemple de stockage de métadonnées dans un fichier HDF5 ici .
la source
store = pd.HDFStore(...)
, alors les attributs peuvent être stockés avecstore.root._v_attrs.key = value
.df = pd.DataFrame(); df.meta = {}
produitUserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access
). (Aucun avertissement n'est donné si l'attribut a déjà été créé comme dansdf = pd.DataFrame(); df.meta = ''; df.meta = {}
).Je viens de rencontrer ce problème moi-même. Depuis pandas 0.13, les DataFrames ont un attribut _metadata sur eux qui persiste à travers les fonctions qui renvoient de nouvelles DataFrames. Semble également survivre à la sérialisation (je n'ai essayé que json, mais j'imagine que hdf est également couvert).
la source
_metadata
ne fait pas partie de l'API publique, je déconseille donc fortement de s'appuyer sur cette fonctionnalité..attrs
fait partie de l'API xray)_metadata
est en fait un attribut de classe, pas un attribut d'instance. Ainsi, les nouvellesDataFrame
instances héritent des précédentes, tant que le module reste chargé. Ne l'utilisez_metadata
pour rien. +1 pourxarray
!Pas vraiment. Bien que vous puissiez ajouter des attributs contenant des métadonnées à la classe DataFrame comme le mentionne @unutbu, de nombreuses méthodes DataFrame renvoient un nouveau DataFrame, vos métadonnées seraient donc perdues. Si vous devez manipuler votre dataframe, la meilleure option serait d'encapsuler vos métadonnées et DataFrame dans une autre classe. Voir cette discussion sur GitHub: https://github.com/pydata/pandas/issues/2485
Il existe actuellement une demande d'extraction ouverte pour ajouter un objet MetaDataFrame, qui prendrait mieux en charge les métadonnées.
la source
Depuis pandas 1.0, peut-être plus tôt, il existe désormais une
Dataframe.attrs
propriété. C'est expérimental, mais c'est probablement ce que vous voudrez à l'avenir. Par exemple:import pandas as pd df = pd.DataFrame([]) df.attrs['instrument_name'] = 'Binky'
Trouvez-le dans la documentation ici .
Essayer cela avec
to_parquet
puisfrom_parquet
, cela ne semble pas persister, alors assurez-vous de vérifier cela avec votre cas d'utilisation.la source
dataclass
pour les métadonnées, puis le sous-classementDataFrame
pour avoir une méthode de chargement / déchargement comme dans le post que vous avez partagé pourrait être une bonne solution.La réponse principale consistant à attacher des attributs arbitraires à l'objet DataFrame est bonne, mais si vous utilisez un dictionnaire, une liste ou un tuple, il émettra une erreur "Pandas ne permet pas la création de colonnes via un nouveau nom d'attribut". La solution suivante fonctionne pour stocker des attributs arbitraires.
from types import SimpleNamespace df = pd.DataFrame() df.meta = SimpleNamespace() df.meta.foo = [1,2,3]
la source
pd.DataFrame._metadata += ["meta"]
. Notez que cette partie est un attribut de Pandas, pas un attribut de votre dataframe spécifiquedf.meta
déclenche un avertissement indiquant que Pandas n'autorise pas la génération de nouvelles colonnes de cette façon.df.meta
est un SimpleNamespace. Les pandas n'essaieront pas de construire une colonne à partir de cela.Comme mentionné dans d'autres réponses et commentaires,
_metadata
ne fait pas partie de l'API publique, ce n'est donc certainement pas une bonne idée de l'utiliser dans un environnement de production. Mais vous voudrez peut-être toujours l'utiliser dans un prototypage de recherche et le remplacer s'il cesse de fonctionner. Et pour le moment, cela fonctionne avecgroupby
/apply
, ce qui est utile. Voici un exemple (que je n'ai pas trouvé dans d'autres réponses):df = pd.DataFrame([1, 2, 2, 3, 3], columns=['val']) df.my_attribute = "my_value" df._metadata.append('my_attribute') df.groupby('val').apply(lambda group: group.my_attribute)
Production:
val 1 my_value 2 my_value 3 my_value dtype: object
la source
Arrivant assez tard à cela, j'ai pensé que cela pourrait être utile si vous avez besoin de métadonnées pour persister sur les E / S. Il existe un package relativement nouveau appelé h5io que j'ai utilisé pour accomplir cela.
Il devrait vous permettre d'effectuer une lecture / écriture rapide à partir de HDF5 pour quelques formats courants, l'un d'entre eux étant un dataframe. Ainsi, vous pouvez, par exemple, mettre un dataframe dans un dictionnaire et inclure des métadonnées en tant que champs dans le dictionnaire. Par exemple:
save_dict = dict(data=my_df, name='chris', record_date='1/1/2016') h5io.write_hdf5('path/to/file.hdf5', save_dict) in_data = h5io.read_hdf5('path/to/file.hdf5') df = in_data['data'] name = in_data['name'] etc...
Une autre option serait de se pencher sur un projet comme xray , qui est plus complexe à certains égards, mais je pense qu'il vous permet d'utiliser des métadonnées et qu'il est assez facile à convertir en DataFrame.
la source
Comme mentionné par @choldgraf, j'ai trouvé que xarray était un excellent outil pour attacher des métadonnées lors de la comparaison des données et du traçage des résultats entre plusieurs dataframes.
Dans mon travail, nous comparons souvent les résultats de plusieurs révisions de firmware et de différents scénarios de test, l'ajout de ces informations est aussi simple que ceci:
df = pd.read_csv(meaningless_test) metadata = {'fw': foo, 'test_name': bar, 'scenario': sc_01} ds = xr.Dataset.from_dataframe(df) ds.attrs = metadata
la source
J'ai cherché une solution et j'ai trouvé que le cadre de pandas avait la propriété
attrs
pd.DataFrame().attrs.update({'your_attribute' : 'value'}) frame.attrs['your_attribute']
Cet attribut restera toujours fidèle à votre cadre chaque fois que vous le passerez!
la source
J'avais le même problème et j'ai utilisé une solution de contournement pour créer un nouveau DF plus petit à partir d'un dictionnaire avec les métadonnées:
meta = {"name": "Sample Dataframe", "Created": "19/07/2019"} dfMeta = pd.DataFrame.from_dict(meta, orient='index')
Ce dfMeta peut ensuite être enregistré à côté de votre DF d'origine dans pickle, etc.
Voir Enregistrement et chargement de plusieurs objets dans un fichier pickle? (Réponse de Lutz) pour une excellente réponse sur l'enregistrement et la récupération de plusieurs dataframes à l'aide de pickle
la source