【问题标题】:Creating an empty MultiIndex创建一个空的 MultiIndex
【发布时间】:2015-04-02 02:09:12
【问题描述】:

我想先创建一个 empty DataFrameMultiIndex,然后再为其分配行。我已经发现空的 DataFrame 不喜欢动态分配 MultiIndex,所以我在创建期间设置了 MultiIndex names。但是,我不想分配 级别,因为这将在稍后完成。这是迄今为止我得到的最好的代码:

def empty_multiindex(names):
    """
    Creates empty MultiIndex from a list of level names.
    """
    return MultiIndex.from_tuples(tuples=[(None,) * len(names)], names=names)

这给了我

In [2]:

empty_multiindex(['one','two', 'three'])

Out[2]:

MultiIndex(levels=[[], [], []],
           labels=[[-1, -1, -1], [-1, -1, -1], [-1, -1, -1]],
           names=[u'one', u'two', u'three'])

In [3]:
DataFrame(index=empty_multiindex(['one','two', 'three']))

Out[3]:
one two three
NaN NaN NaN

好吧,我对这些 NaN 没有用处。稍后我可以轻松地删除它们,但这显然是一个骇人听闻的解决方案。谁有更好的?

【问题讨论】:

  • 你为什么要这样做?
  • @AndyHayden 我正在尝试编写一个足够通用的函数来处理任意数量的名称。我的任务是创建频率表,其中包含可以在仪表板中折叠和展开的非常任意和异想天开的总计和小计和小计。在将数据帧传递给 Django 之前创建数据帧让我的生活更轻松。
  • 为什么将其作为 MI 而不是列?一般来说,pandas 在逐行更新方面非常糟糕(因为它每次都必须复制整个数据)。你能稍后(在施工后)把它做成 MI 吗?
  • @AndyHayden 通过分配创建标签 (df2.loc[(name, key2, True), :] = df1.loc[(key1, key2), :].sum()) 比在分配之前通过附加到 Series 来折磨Series 更方便和易读。并且为索引和数据维护并行 DataFrame 会更糟。
  • @AndyHayden dict 不会给我 pandas DataFrame 索引和 sum() 等可以与索引结合的方法。我同意可能有更好的解决方案(例如从头开始创建一个可以满足我需求的对象)。但在这一点上,我正在优化开发时间而不是处理时间。

标签: python pandas multi-index


【解决方案1】:

解决方案是省略标签。这对我来说很好:

>>> my_index = pd.MultiIndex(levels=[[],[],[]],
                             labels=[[],[],[]],
                             names=[u'one', u'two', u'three'])
>>> my_index
MultiIndex(levels=[[], [], []],
           labels=[[], [], []],
           names=[u'one', u'two', u'three'])
>>> my_columns = [u'alpha', u'beta']
>>> df = pd.DataFrame(index=my_index, columns=my_columns)
>>> df
Empty DataFrame
Columns: [alpha, beta]
Index: []
>>> df.loc[('apple','banana','cherry'),:] = [0.1, 0.2]
>>> df
                    alpha beta
one   two    three            
apple banana cherry   0.1  0.2

希望有帮助!

对于 Pandas 版本 >= 0.25.1: 关键字labels 已替换为codes

【讨论】:

  • [[],[],[]] 可以根据需要替换为 [[]]*3
  • 这会在 Pandas '0.25.1' 上引发弃用警告。
  • @buechel 关键字 labels 已在 0.25.1 中替换为 codes
【解决方案2】:

另一个可能更简单的解决方案是使用函数set_index

>>> import pandas as pd
>>> df = pd.DataFrame(columns=['one', 'two', 'three', 'alpha', 'beta'])
>>> df = df.set_index(['one', 'two', 'three'])
>>> df
Empty DataFrame
Columns: [alpha, beta]
Index: []
>>> df.loc[('apple','banana','cherry'),:] = [0.1, 0.2]
>>> df
                    alpha beta
one   two    three            
apple banana cherry   0.1  0.2

【讨论】:

    【解决方案3】:

    在显式定义索引时,使用pd.MultiIndex.from_arrays 可以实现更简洁的解决方案:

    import pandas as pd
    ind = pd.MultiIndex.from_arrays([[]] * 3, names=(u'one', u'two', u'three'))
    df = pd.DataFrame(columns=['alpha', 'beta'], index=ind)
    df.loc[('apple','banana','cherry'), :] = [4, 3]
    
                         alpha  beta
    one   two    three              
    apple banana cherry      4     3
    

    【讨论】:

      【解决方案4】:

      使用 pd.MultiIndex.from_tuples 可能更直接。

      import pandas as pd
      ind = pd.MultiIndex.from_tuples([], names=(u'one', u'two', u'three'))
      df = pd.DataFrame(columns=['alpha', 'beta'], index=ind)
      df.loc[('apple','banana','cherry'), :] = [4, 3]
      df
      
                            alpha beta
      one     two     three       
      apple   banana  cherry    4    3
      

      【讨论】:

        猜你喜欢
        • 2020-05-17
        • 2018-08-20
        • 2016-12-18
        • 2019-03-21
        • 1970-01-01
        相关资源
        最近更新 更多