IPython的一个有用功能是它的选项卡完成,除其他外,无需记住pandas.DataFrame
列名称。
,例如,假设我们有
df = pd.DataFrame({'bar': [1, 2], 'baz': [3, 4], 'bap': [5, 6]})
将df
作为
bap bar baz
0 5 1 3
1 6 2 4
然后我们可以输入
df.<Tab>
它会将bap
,bar
和baz
(以及其他)显示为成员,并尝试完成它们。
不幸的是,这种有用的功能在分层数据帧中部分消失了。例如,如果我们将事情改为
df = pd.DataFrame({
('foo', 'bar'): [1, 2],
('foo', 'baz'): [3, 4],
('bap', ''): [5, 6]})
将df
作为
bap foo
bar baz
0 5 1 3
1 6 2 4
然后df.<Tab>
将无法自动填充bap
或foo
。
使这项工作的正确方法是什么?我写了一个黑客来做这个(回答如下),但我对它依赖Python monkey-patching感到不满。其他答案将受到欢迎。
答案 0 :(得分:0)
应用以下猴子补丁似乎可以消除问题的症状:
_orig_dir = getattr(pd.DataFrame, '__dir__')
def _mutilevel_aware_dir(df):
multilevels = [tup for tup in df.columns if isinstance(tup, tuple)]
return _orig_dir(df) + [tup[0] for tup in multilevels]
setattr(pd.DataFrame, '__dir__', _mutilevel_aware_dir)
_orig_get_attr = getattr(pd.DataFrame, '__getattr__')
def _mutilevel_aware_getattr(df, name):
return _orig_get_attr(df, name)
setattr(pd.DataFrame, '__getattr__', _mutilevel_aware_getattr)
IPython显然间接使用DataFrame
的{{3}}方法进行自动完成。
第一个函数在内部扫描元组,如果遇到它们,则将它们的第一个元素作为“虚拟”成员返回。第二个函数抓取__getattr__
来处理访问这样一个虚拟成员时将返回的内容。
将这些修补到课堂上似乎可以胜任。然而,这是一个相当暴力的解决方案,它可能具有我不知道的副作用。