2013-05-11 56 views
1

我正在从一项调查中获得一个相当复杂的数据集的Pandas表示形式。到目前为止,似乎具有多索引的一维变量序列是存储和处理这些数据的最佳选择。具有可变长度多指数的pandas数据框用NaN替换值

每个变量名称由一个“路径”组成,以唯一标识该特定响应。这些路径长度各不相同。我试图弄清楚,如果我误解了分级索引应该如何工作,或者如果我遇到了一个bug。看起来Pandas在将它们连接到数据集时将“较短的索引”填充到最大长度,并在此过程中破坏该值。

例如,测试失败:

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 

有趣的是,填充了空字符串,而不是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) 

并打印此:

   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 

我在这里错过了什么?谢谢!

+0

MultiIndex不能有不同长度的索引。每个索引项目必须具有相同的长度。如果你想用NaN之外的东西来填充它们,你必须自己做。 – BrenBarn 2013-05-11 22:24:31

+0

问题是用NaN填充它们也会破坏价值。用NaN手工填充它们也具有相同的结果。 – easel 2013-05-11 23:59:15

回答

1

避免在索引中使用NaN。除此之外,您需要一个不同的模式来表示路径/案例/数据之间的关系。事实上,您需要可变数量的MultiIndex级别是一个强有力的提示,并且大小写列仅用于几条路径。我将在不同的DataFrame中分割节点,路径和案例数据。在下面的例子中,我展示了如何表示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 
+0

谢谢。这基本上是我开始移动的方向,尽管我仍然在找出处理索引的最佳方法,以便在需要时可以将数据帧连接在一起进行分析。 – easel 2013-05-19 14:55:39

+0

您是否检查http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging? – 2013-05-21 18:59:40

相关问题