gpt4 book ai didi

python - 通过连接传播 pandas 系列元数据

转载 作者:太空狗 更新时间:2023-10-30 03:02:05 25 4
gpt4 key购买 nike

我希望能够将元数据附加到数据帧系列(特别是原始文件名),以便在加入两个数据帧后,我可以看到每个系列来自何处的元数据。

我看到有关 _metadata(herehere)的 github 问题,包括一些与当前 _metadata 属性(here)相关的问题,但在 Pandas 文档。

到目前为止,我可以修改 _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

最佳答案

我认为这样的事情会奏效(如果不行,请提交错误报告,虽然支持有点前沿,但 join 方法可能不会一直调用它。那就是有点未经测试)。

查看此 issue获取更详细的示例/错误修复。

DataFrame._metadata = ['name','filename']


def __finalize__(self, other, method=None, **kwargs):
"""
propagate metadata from other to self

Parameters
----------
other : the object from which to get the attributes that we are going
to propagate
method : optional, a passed method name ; possibly to take different
types of propagation actions based on this

"""

### you need to arbitrate when their are conflicts

for name in self._metadata:
object.__setattr__(self, name, getattr(other, name, None))
return self

DataFrame.__finalize__ = __finalize__

因此,这将用您的自定义终结器替换 DataFrame 的默认终结器。在我指出的地方,您需要放置一些可以在冲突之间进行仲裁的代码。这就是默认情况下不这样做的原因,例如frame1 的名称为“foo”,frame2 的名称为“bar”,当方法是 __add__ 时你会做什么,另一个方法呢?。让我们知道您做了什么以及结果如何。

这只是对 DataFrame 的替换(如果你愿意,你可以简单地执行默认操作),即将其他人传播给自己;你也可以不设置任何东西,除非在方法的特殊情况下。

这个方法是为了在子类中被覆盖,这就是为什么你在这里进行猴子修补(而不是子类化,这在大多数情况下是矫枉过正的)。

关于python - 通过连接传播 pandas 系列元数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23200524/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com