制作IPython Tab-Complete Hierarchical pandas DataFrames

时间:2015-05-27 10:38:39

标签: python pandas ipython

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>

它会将bapbarbaz(以及其他)显示为成员,并尝试完成它们。

不幸的是,这种有用的功能在分层数据帧中部分消失了。例如,如果我们将事情改为

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>将无法自动填充bapfoo

使这项工作的正确方法是什么?我写了一个黑客来做这个(回答如下),但我对它依赖Python monkey-patching感到不满。其他答案将受到欢迎。

1 个答案:

答案 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__来处理访问这样一个虚拟成员时将返回的内容。

将这些修补到课堂上似乎可以胜任。然而,这是一个相当暴力的解决方案,它可能具有我不知道的副作用。