我希望能夠將元數據附加到一系列數據框(特別是原始文件名),以便在加入兩個數據框後,我可以看到每個系列來自哪裏的元數據。通過連接傳播大熊貓系列元數據
我看到有關_metadata
(here,here)github上的問題,包括一些與當前_metadata
屬性(here),但沒有在大熊貓文檔。
到目前爲止,我可以修改_metadata
屬性以假定允許保存元數據,但在加入後得到AttributeError
。
df1 = pd.DataFrame(np.random.randint(0, 4, (6, 3)))
df2 = pd.DataFrame(np.random.randint(0, 4, (6, 3)))
df1._metadata.append('filename')
df1[df1.columns[0]]._metadata.append('filename')
for c in df1:
df1[c].filename = 'fname1.csv'
df2[c].filename = 'fname2.csv'
df1[0]._metadata # ['name', 'filename']
df1[0].filename # fname1.csv
df2[0].filename # fname2.csv
df1[0][:3].filename # fname1.csv
mgd = pd.merge(df1, df2, on=[0])
mgd['1_x']._metadata # ['name', 'filename']
mgd['1_x'].filename # raises AttributeError
任何方式來保存這個?
更新:結語
正如所討論的here,__finalize__
無法跟蹤系列,它們是數據幀的成員中,只有獨立的系列。因此,現在我將通過維護附加到數據框的元數據字典來跟蹤系列級元數據。我的代碼如下所示:
def cust_merge(d1, d2):
"Custom merge function for 2 dicts"
...
def finalize_df(self, other, method=None, **kwargs):
for name in self._metadata:
if method == 'merge':
lmeta = getattr(other.left, name, {})
rmeta = getattr(other.right, name, {})
newmeta = cust_merge(lmeta, rmeta)
object.__setattr__(self, name, newmeta)
else:
object.__setattr__(self, name, getattr(other, name, None))
return self
df1.filenames = {c: 'fname1.csv' for c in df1}
df2.filenames = {c: 'fname2.csv' for c in df2}
pd.DataFrame._metadata = ['filenames']
pd.DataFrame.__finalize__ = finalize_df
你說「這只是替代DataFrame」,你的意思是它不適用於系列? (我以爲系列是DF的一個子類) – beardc
不,它適用於Series,但它有一個不同的''_metadata''(在''core/series.py''中定義;它已經包含了名字,所以你想要以處理這一點)。所以你可以做一個''Series .__ finalize__ = __ finalize__''' – Jeff