【发布时间】:2020-12-12 20:19:08
【问题描述】:
在 Pandas 中,我一直使用自定义对象作为列标签,因为它们为特定于列的信息/方法提供了丰富/灵活的功能。例如,您可以设置自定义fmt_fn 来格式化每一列(注意这只是一个示例,我的实际列标签对象更复杂):
In [100]: class Col:
...: def __init__(self, name, fmt_fn):
...: self.name = name
...: self.fmt_fn = fmt_fn
...: def __str__(self):
...: return self.name
...:
In [101]: sec_col = Col('time', lambda val: str(timedelta(seconds=val)).split('.')[0])
In [102]: dollar_col = Col('money', lambda val: '${:.2f}'.format(val))
In [103]: foo = pd.DataFrame(np.random.random((3, 2)) * 1000, columns = [sec_col, dollar_col])
In [104]: print(foo) # ugly
time money
0 773.181402 720.997051
1 33.779925 317.957813
2 590.750129 416.293245
In [105]: print(foo.to_string(formatters = [col.fmt_fn for col in foo.columns])) # pretty
time money
0 0:12:53 $721.00
1 0:00:33 $317.96
2 0:09:50 $416.29
好的,所以我一直很高兴地这样做了一段时间,但是最近我遇到了 Pandas 的一部分,它不支持这一点。具体来说,方法 to_hdf/read_hdf will fail 在具有自定义列标签的 DataFrames 上。这对我来说不是一个交易破坏者。我可以使用 pickle 代替 HDF5,但会损失一些效率。
但更大的问题是,Pandas 通常是否支持自定义对象作为列标签?换句话说,我是应该继续这样使用 Pandas,还是以后会在 Pandas 的其他部分(HDF5 除外)出现这种情况,给我带来未来的痛苦?
PS。附带说明一下,如果您当前不使用自定义对象作为列标签,我不介意您是否也解决列特定信息的问题,例如上面示例中的 fmt_fn。
【问题讨论】:
-
有趣的问题,因为我从未见过对象作为 DataFrame 中的列传递。我建议不要使用这种用法。如果您需要灵活性,可以保留列名和底层对象的字典。
-
如果为每个 DataFrame 维护一个与
foo.columns平行的单独数据结构,而不是简单地将特定于列的数据放入foo.columns,那将是糟糕的设计 (IMO)。我只会在必要时这样做,即如果 Pandas 真的不支持自定义对象作为列标签。因此我发布了这个问题。 -
数据框的列只是一个索引。似乎唯一的要求是对象是可散列的。 pandas.pydata.org/pandas-docs/stable/generated/…