Python 创建空的多重索引

Python 创建空的多重索引,python,pandas,multi-index,Python,Pandas,Multi Index,我想先创建一个空的数据帧,然后再将行分配给它。我已经发现空数据帧不喜欢动态分配多索引,所以我在创建过程中设置多索引名称。但是,我不想分配级别,因为这将在稍后完成。这是迄今为止我得到的最好的代码: def empty_multiindex(names): """ Creates empty MultiIndex from a list of level names. """ return MultiIndex.from_tuples(tuples=[(None,)

我想先创建一个空的数据帧,然后再将行分配给它。我已经发现空数据帧不喜欢动态分配多索引,所以我在创建过程中设置多索引名称。但是,我不想分配级别,因为这将在稍后完成。这是迄今为止我得到的最好的代码:

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'])


嗯,我不喜欢这些南。我可以很容易地在以后删除它们,但这显然是一个黑客的解决方案。有人有更好的吗?

解决办法是省去标签。这对我来说很好:

>>> 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

希望有帮助

另一个可能更简单的解决方案是使用函数
set\u 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

使用
pd.MultiIndex.from_array
可以在显式定义索引时提供更简洁的解决方案:

将熊猫作为pd导入
ind=pd.MultiIndex.from_数组([[]]*3,name=(u'one',u'two',u'three'))
df=pd.DataFrame(列=['alpha','beta'],索引=ind)
df.loc[(‘苹果’、‘香蕉’、‘樱桃’),:]=[4,3]
α-β
123
苹果香蕉樱桃43

使用pd.MultiIndex.from\u元组可能更简单

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

为什么要这样做?@AndyHayden我正在尝试编写一个足够通用的函数来处理任意数量的名称。我的任务是创建频率表,其中包含非常任意和异想天开的总计、小计和子总计,可以在仪表板中折叠和展开。在将数据帧传递给Django之前创建数据帧可以让我的生活更轻松。为什么要将其作为MI而不是列?通常,pandas在逐行更新方面非常糟糕(因为它每次都必须复制整个数据)。您能在以后(构建之后)将其设置为MI吗?@AndyHayden通过赋值创建标签(
df2.loc[(name,key2,True),:]=df1.loc[(key1,key2),:].sum()
)比在赋值之前附加到
序列更方便、更可读。而为索引和数据维护并行数据帧则会更糟糕。@AndyHayden一个dict不会给我提供数据帧索引和sum()之类的方法,我可以将它们与索引结合起来。我同意可能有更好的解决方案(比如从头创建一个符合我要求的对象)。但在这一点上,我正在优化开发人员的时间,而不是处理时间。
[[]、[]、[]]
可以根据需要替换为
[[[]]*3
。这会在Pandas'0.25.1'上抛出一个弃用警告。@buechel关键字
标签
在0.25.1中被替换为
代码
,直到2021年(v.1.2.3)
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