Pandalar DataFrame'e meta bilgi / meta veri ekleme


93

Pandaların DataFrame'ine bazı meta bilgiler / meta veriler eklemek mümkün müdür?

Örneğin, verileri ölçmek için kullanılan aletin adı, sorumlu alet vb.

Çözümlerden biri, bu bilgilerle bir sütun oluşturmak olabilir, ancak her satırda tek bir bilgi parçasını depolamak boşa gider!


Lütfen bir başlangıç ​​gibi görünen güncellenmiş deneysel nitelik 'attrs'den bahseden @ryanjdillon cevabına (şu anda altta gömülüdür) dikkat edin, belki
JohnE

Yanıtlar:


87

Elbette, çoğu Python nesnesi gibi, bir şuna yeni nitelikler ekleyebilirsiniz pandas.DataFrame:

import pandas as pd
df = pd.DataFrame([])
df.instrument_name = 'Binky'

Bununla birlikte, bir DataFrame için özellik ekleyebilirsiniz kullanımın oldukça işlemleri (örneğin DataFrame üzerinde gerçekleştirilen groupby, pivot, joinveya locyeni bir DataFrame döndürebilir sadece birkaç isim) olmadan ekli meta veriler. Pandalar, DataFrames'e eklenmiş meta verileri yaymak için henüz sağlam bir yönteme sahip değildir .

Meta verilerin bir dosyada saklanması mümkündür. Meta verilerin bir HDF5 dosyasında nasıl saklanacağına dair bir örneği burada bulabilirsiniz .


5
Enstrüman adı seçiminiz için +1! Bu ekstra özellikleri HDFStore'a aktarmaya çalışan herhangi bir deneyiminiz var mı?
Dan Allan

4
@DanAllan: Eğer store = pd.HDFStore(...), o zaman öznitelikler ile saklanabilir store.root._v_attrs.key = value.
unutbu

3
Bunu kullanabilecek herhangi biri için: Dokümanlar bununla ilgili bir bölüm ekledi. pandas.pydata.org/pandas-docs/dev/cookbook.html#hdfstore
Dan Allan


5
Pandalar 0.23.1'de, bir sözlük, liste veya tuple atayarak yeni bir öznitelik oluşturmak bir uyarı verir (yani df = pd.DataFrame(); df.meta = {}üretir UserWarning: 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). (Öznitelik halihazırda olduğu gibi oluşturulmuşsa hiçbir uyarı verilmez df = pd.DataFrame(); df.meta = ''; df.meta = {}).
teichert

14

Pandalar 1.0'dan itibaren, muhtemelen daha önce, artık bir Dataframe.attrsözellik var. Deneyseldir, ancak gelecekte isteyeceğiniz şey muhtemelen budur. Örneğin:

import pandas as pd
df = pd.DataFrame([])
df.attrs['instrument_name'] = 'Binky'

Buradaki belgelerde bulun .

Bunu denemek to_parquetve sonra from_parquet, kalıcı görünmüyor, bu yüzden kullanım durumunuzla bunu kontrol ettiğinizden emin olun.


Bu ilginç ve copy / loc / iloc için var gibi görünüyor, ancak groupby için değil.
JohnE

Sadece bir öneri, ama nasıl kullanılacağına dair bir örnek gösterebilir misiniz? Dokümantasyon temelde hiçbir şey değildir, ancak sadece onunla oynadığımda boş bir sözlük olarak başlatıldığını ve bir sözlük olması gerekmesine rağmen elbette bir liste içine yerleştirilebilecek şekilde ayarlandığını görebiliyorum. Örneğin.
JohnE

1
Gerekirse parke dosyalarına özel meta verilerin nasıl ekleneceğini gösterdiği için bu Stackoverflow tartışmasını yararlı bulabilirsiniz
rdmolony

1
@rdmolony Bu harika. dataclassMeta veriler için a kullanıp daha sonra DataFramepaylaştığınız gönderideki gibi yükleme / boşaltma yapan bir yönteme sahip olmak için alt sınıflandırma yapmak güzel bir çözüm olabilir.
ryanjdillon

1
Bu güzel. Kabul edilen cevabın aksine, bu turşudan kaydettikten ve yükledikten sonra özellikleri korur!
CGFoX

13

Bu sorunla kendim karşılaştım. Pandalar 0.13'ten itibaren, DataFrame'ler, yeni DataFrame'leri döndüren işlevler aracılığıyla kalıcı olan bir _metadata özniteliğine sahiptir. Ayrıca serileştirmeden sağ kurtulmuş gibi görünüyor (sadece json'u denedim, ancak hdf'nin de kapsandığını hayal ediyorum).


16
_metadatagenel API'nin bir parçası olmadığı için bu işlevselliğe güvenmemenizi şiddetle tavsiye ederim.
shoyer

@Stephan bunu detaylandırır mısın lütfen? Genel API'nin bir parçası olmak neden önemlidir? İfadeniz 0.15 sürümü için de doğru mu?
TomCho

1
@TomCho evet, bu cevap bugün hala geçerli. Meta veriyi destekleyen etiketli bir dizinin alternatif bir örneği için xray'e ( github.com/xray/xray ) bakabilirsiniz , özellikle çok boyutlu verileriniz varsa ( .attrsxray API'nin bir parçasıdır)
shoyer

17
_metadataaslında bir sınıf niteliğidir, bir örnek niteliği değildir. Dolayısıyla DataFrame, modül yüklü kaldığı sürece yeni örnekler öncekilerden miras alınır. Hiçbir _metadataşey için kullanmayın . +1 xarray!
j08lue

1
_metadata - günümü kurtaran desteklenmeyen bir özellik! Teşekkür ederim.
joctee

12

Pek sayılmaz. @Unutbu'nun bahsettiği gibi DataFrame sınıfına meta veriler içeren öznitelikler ekleyebilseniz de, birçok DataFrame yöntemi yeni bir DataFrame döndürür, bu nedenle meta verileriniz kaybolur. Veri çerçevenizi düzenlemeniz gerekiyorsa, en iyi seçenek meta verilerinizi ve DataFrame'inizi başka bir sınıfta sarmalamak olacaktır. GitHub'daki bu tartışmaya bakın: https://github.com/pydata/pandas/issues/2485

Şu anda meta verileri daha iyi destekleyecek bir MetaDataFrame nesnesi eklemek için açık bir çekme isteği var .


8

DataFrame nesnesine rastgele öznitelikler eklemenin en iyi yanıtı iyidir, ancak bir sözlük, liste veya tuple kullanırsanız, "Pandalar sütunların yeni bir öznitelik adıyla oluşturulmasına izin vermez" hatası verir. Aşağıdaki çözüm, rastgele öznitelikleri depolamak için çalışır.

from types import SimpleNamespace
df = pd.DataFrame()
df.meta = SimpleNamespace()
df.meta.foo = [1,2,3]

Ayrıca, bunun veri çerçevenizin kopyalarında kalmasını istiyorsanız, yapmanız gerekir pd.DataFrame._metadata += ["meta"]. Bu parçanın, belirli veri çerçevenizin bir özelliği değil, Pandaların bir özelliği olduğunu unutmayın
bscan

Bu yaklaşım, df.metaPandaların bu şekilde yeni sütunların oluşturulmasına izin vermediğine dair bir uyarıyı tetiklediği için artık çalışmayacaktır .
anishtain4

@ anishtain4, Pandas 25.1 ile test ettim (~ 2 hafta önce yayınlandı) ve bu kod hala benim için çalışıyor. df.metaBir SimpleNamespace olduğundan bu uyarı tetiklenmez . Pandalar ondan bir sütun oluşturmaya çalışmayacak.
bscan

6

Diğer yanıtlarda ve yorumlarda belirtildiği gibi _metadata, genel API'nin bir parçası değildir, bu nedenle onu bir üretim ortamında kullanmak kesinlikle iyi bir fikir değildir. Ancak yine de bir araştırma prototipinde kullanmak ve çalışmayı durdurursa değiştirmek isteyebilirsiniz. Ve şu anda groupby/ ile çalışıyor apply, bu da yardımcı oluyor. Bu bir örnek (diğer cevaplarda bulamadığım bir örnek):

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)

Çıktı:

val
1    my_value
2    my_value
3    my_value
dtype: object

4

Buna oldukça geç gelince, I / O üzerinde devam etmek için meta verilere ihtiyacınız varsa bunun faydalı olabileceğini düşündüm. Bunu başarmak için kullandığım h5io adında nispeten yeni bir paket var .

Biri veri çerçevesi olan birkaç yaygın format için HDF5'ten hızlı bir okuma / yazma yapmanıza izin vermelidir. Böylece, örneğin, bir sözlüğe bir veri çerçevesi koyabilir ve meta verileri sözlüğe alanlar olarak dahil edebilirsiniz. Örneğin:

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

Başka bir seçenek de xray gibi bazı yönlerden daha karmaşık olan bir projeye bakmak olabilir , ancak meta verileri kullanmanıza izin verdiğini ve bir DataFrame'e dönüştürmenin oldukça kolay olduğunu düşünüyorum.


4

Ben bulduk @choldgraf tarafından belirtildiği gibi xarray verilerini karşılaştırarak ve birkaç dataframes arasındaki sonuçlar çizdirirken meta bağlanması için mükemmel bir araç olduğunu.

Çalışmamda, genellikle birkaç ürün yazılımı revizyonunun ve farklı test senaryolarının sonuçlarını karşılaştırıyoruz ve bu bilgileri eklemek şu kadar basit:

df = pd.read_csv(meaningless_test)
metadata = {'fw': foo, 'test_name': bar, 'scenario': sc_01}
ds = xr.Dataset.from_dataframe(df)
ds.attrs = metadata

2

Bir çözüm arıyordum ve pandalar çerçevesinin özelliğe sahip olduğunu buldum attrs

pd.DataFrame().attrs.update({'your_attribute' : 'value'})
frame.attrs['your_attribute']

Bu özellik, onu her geçtiğinizde her zaman çerçevenize yapışacaktır!


Özniteliklerin deneysel olduğunu ve uyarı vermeden değişebileceğini unutmayın, ancak bu çok basit bir çözümdür. Yeni veri çerçevelerine attr aktarımı olup olmadığını merak ediyorum.
Liquidgenius

Ne yazık ki, öznitelikler yeni veri çerçevelerine kopyalanmıyor :(
Adam

1

Aynı sorunu yaşıyordum ve meta verilerle bir sözlükten yeni, daha küçük bir DF oluşturmak için bir geçici çözüm kullandım:

    meta = {"name": "Sample Dataframe", "Created": "19/07/2019"}
    dfMeta = pd.DataFrame.from_dict(meta, orient='index')

Bu dfMeta daha sonra orijinal DF'nizle birlikte turşu vb.

Turşu dosyasında birden çok nesneyi kaydetme ve yükleme bölümüne bakın (Lutz'un cevabı) turşu kullanarak birden fazla veri çerçevesini kaydetme ve geri alma konusunda mükemmel yanıt

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.