Python 具有可变长度多重索引的数据帧将值替换为NaN

Python 具有可变长度多重索引的数据帧将值替换为NaN,python,pandas,Python,Pandas,我正在处理一个来自调查的相当复杂的数据集的熊猫表示。到目前为止,似乎具有多个索引的一维变量系列最适合存储和处理这些数据 每个变量名都由一个“路径”组成,以唯一标识该特定响应。这些路径的长度各不相同。我试图弄清楚我是否误解了层次索引应该如何工作,或者我是否遇到了一个bug。在将短索引连接到数据集时,熊猫似乎将其“填充”到最大长度,并在该过程中破坏该值 例如,此测试失败: def test_dataframe_construction1(self): case1 = pd.Series(Tr

我正在处理一个来自调查的相当复杂的数据集的熊猫表示。到目前为止,似乎具有多个索引的一维变量系列最适合存储和处理这些数据

每个变量名都由一个“路径”组成,以唯一标识该特定响应。这些路径的长度各不相同。我试图弄清楚我是否误解了层次索引应该如何工作,或者我是否遇到了一个bug。在将短索引连接到数据集时,熊猫似乎将其“填充”到最大长度,并在该过程中破坏该值

例如,此测试失败:

def test_dataframe_construction1(self):
    case1 = pd.Series(True, pd.MultiIndex.from_tuples([
        ('a1', 'b1', 'c1'),
        ('a2', 'b2', 'c2', 'd1', 'e1'),
        ]))
    case2 = pd.Series(True, pd.MultiIndex.from_tuples([
        ('a3', 'b3', 'c3'),
        ('a4', 'b4', 'c4', 'd2', 'e2'),
        ]))
    df = pd.DataFrame({
        'case1': case1,
        'case2': case2
    })
    logger.debug(df)
    self.assertEquals(df['case1'].loc['a1'].any(), True)
然后打印这个:

a1 b1 c1 nan nan   NaN   NaN
a2 b2 c2 d1  e1   True   NaN
a3 b3 c3 nan nan   NaN   NaN
a4 b4 c4 d2  e2    NaN  True
                case1 case2
a1 b1 c1        True   NaN
a2 b2 c2 d1 e1  True   NaN
a3 b3 c3         NaN  True
a4 b4 c4 d2 e2   NaN  True
有趣的是,用空字符串而不是NaN填充“较短”的索引会导致我预期的行为:

def test_dataframe_construction2(self):
    case1 = pd.Series(True, pd.MultiIndex.from_tuples([
        ('a1', 'b1', 'c1', '', ''),
        ('a2', 'b2', 'c2', 'd1', 'e1'),
    ]))
    case2 = pd.Series(True, pd.MultiIndex.from_tuples([
        ('a3', 'b3', 'c3', '', ''),
        ('a4', 'b4', 'c4', 'd2', 'e2'),
    ]))
    df = pd.DataFrame({
        'case1': case1,
        'case2': case2
    })
    logger.debug(df)
    self.assertEquals(df['case1'].loc['a1'].any(), True)
然后打印这个:

a1 b1 c1 nan nan   NaN   NaN
a2 b2 c2 d1  e1   True   NaN
a3 b3 c3 nan nan   NaN   NaN
a4 b4 c4 d2  e2    NaN  True
                case1 case2
a1 b1 c1        True   NaN
a2 b2 c2 d1 e1  True   NaN
a3 b3 c3         NaN  True
a4 b4 c4 d2 e2   NaN  True

我错过了什么?谢谢

避免在索引中使用NaN。此外,还需要一个不同的模式来表示路径/案例/数据之间的关系。事实上,您需要可变数量的多索引级别,这是一个强烈的提示,而且case列看起来只使用几个路径。我会将节点、路径和案例数据拆分为单独的数据帧。在下面的示例中,我展示了如何表示case1的第一条路径

import pandas as pd
from itertools import product

node_names = ['%s%d' % t for t in product('abcd', range(1, 5))]
nodes = pd.DataFrame({'node': node_names})
nodes.index.name = 'id'

path_nodes = pd.DataFrame({'path_id': [0, 0, 0],
                           'node_id': [0, 4, 8],
                           'position':[0, 1, 2]})

data = pd.DataFrame({'path_id': [0],
                     'case': [1],
                     'data': [True]})
In [113]: nodes
Out[113]: 
   node
id     
0    a1
1    a2
2    a3
3    a4
4    b1
5    b2
6    b3
7    b4
8    c1
...

In [114]: path_nodes
Out[114]: 
   node_id  path_id  position
0        0        0         0
1        4        0         1
2        8        0         2

In [115]: data
Out[115]: 
   case  data  path_id
0     1  True        0

避免在索引中使用NaN。此外,还需要一个不同的模式来表示路径/案例/数据之间的关系。事实上,您需要可变数量的多索引级别,这是一个强烈的提示,而且case列看起来只使用几个路径。我会将节点、路径和案例数据拆分为单独的数据帧。在下面的示例中,我展示了如何表示case1的第一条路径

import pandas as pd
from itertools import product

node_names = ['%s%d' % t for t in product('abcd', range(1, 5))]
nodes = pd.DataFrame({'node': node_names})
nodes.index.name = 'id'

path_nodes = pd.DataFrame({'path_id': [0, 0, 0],
                           'node_id': [0, 4, 8],
                           'position':[0, 1, 2]})

data = pd.DataFrame({'path_id': [0],
                     'case': [1],
                     'data': [True]})
In [113]: nodes
Out[113]: 
   node
id     
0    a1
1    a2
2    a3
3    a4
4    b1
5    b2
6    b3
7    b4
8    c1
...

In [114]: path_nodes
Out[114]: 
   node_id  path_id  position
0        0        0         0
1        4        0         1
2        8        0         2

In [115]: data
Out[115]: 
   case  data  path_id
0     1  True        0

多重索引不能有不同长度的索引。每个索引项必须具有相同的长度。如果你想用NaN以外的东西填充它们,你必须自己做。问题是用NaN填充它们也会破坏价值。手动填充NaN也有相同的结果。多索引不能有不同长度的索引。每个索引项必须具有相同的长度。如果你想用NaN以外的东西填充它们,你必须自己做。问题是用NaN填充它们也会破坏价值。手工填充NaN也有同样的效果。谢谢。这基本上是我开始移动的方向,尽管我仍在寻找处理索引的最佳方法,以便在需要时将数据帧重新连接在一起进行分析。您检查了吗?谢谢。这基本上是我开始移动的方向,尽管我仍在寻找处理索引的最佳方法,以便在需要时将数据帧重新连接在一起进行分析。你检查过了吗?