2013-05-11 2 views
1

저는 설문 조사에서 나오는 상당히 복잡한 데이터 세트의 팬더 표현을 사용하고 있습니다. 지금까지는 다중 인덱스가있는 일차원 변수 시리즈가이 데이터를 저장하고 작업하는 데 가장 적합하다고 생각합니다.가변 길이 multiindex를 사용하는 pandas 데이터 프레임은 NaN으로 값을 대체합니다.

각 변수 이름은 특정 응답을 고유하게 식별하는 "경로"로 구성됩니다. 이 경로는 다양한 길이입니다. 나는 계층 적 인덱스가 어떻게 작동해야하는지 오해하고 있는지, 아니면 내가 버그에 부딪쳤을지를 알기 위해 노력하고 있습니다. 마치 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

다중 인덱스는 다른 길이의 인덱스를 가질 수 없습니다. 각 색인 항목의 길이는 동일해야합니다. NaN 이외의 다른 것을 덧붙이려면 직접해야합니다. – BrenBarn

+0

NaN으로 패딩하면 값이 손상된다는 문제가 있습니다. 손으로 NaN으로 채우는 것도 같은 결과를 낳습니다. – easel

답변

1

색인에서 NaN을 사용하지 마십시오. 그 외에도 경로/사례/데이터 간의 관계를 나타 내기 위해 다른 스키마가 필요합니다. 다양한 수의 MultiIndex 레벨이 필요하다는 사실은 강력한 힌트이며 사례 열은 몇 개의 경로 만 사용하는 것처럼 보입니다. 노드, 경로 및 사례 데이터를 별도의 DataFrames로 분할했습니다. 아래 예제에서는 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

+0

http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging을 확인 했습니까? –

관련 문제