2014-09-05 2 views
1

을 dataframe 팬더와 다른 수준에서 키의 범위를 기반으로 multiindexed 행에서 슬라이스 :편리한 방법은 내가 multiindexed 팬더가 같은 종류의 dataframe이

Year, Month, Day의 행을 multiindexed있다
data = np.random.random((1800,9)) 
col = pd.MultiIndex.from_product([('A','B','C'),('a','b','c')]) 

year = range(2006,2011) 
month = range(1,13) 
day = range(1,31) 

idx = pd.MultiIndex.from_product([year,month,day], names=['Year','Month','Day']) 

df1 = pd.DataFrame(data, idx, col) 

. DatetimeIndex가있는 것처럼이 Dataframe에서 행을 선택할 수 있기를 원합니다.

DatetimeIndex와 등가 DataFrame은 다음과 같습니다

all(df2.ix['2006-06-06':'2008-10-11'] == df1'insert expression here') 

내가 통해 단면을 선택할 수 있습니다 알고 True

동일하게 :

idx = pd.DatetimeIndex(start='2006-01-01', end='2010-12-31', freq='d') 
timeidx = [ix for ix in idx if ix.day < 29] 
df2 = pd.DataFrame(data, timeidx, col) 

는 내가하고 싶은 것은 이것이다 df1.xs('2006', level='Year'), 그러나 나는이 인덱스를 반대로 사용하도록 강요당한 것처럼 df2에 대해 수행 된 작업을 복제하기위한 쉬운 방법이 필요합니다. DatetimeIndex에 추가합니다.

+0

다른 세 개를 결합하여 새 열을 만들 수 없습니까? 또는 귀하의 경우 실현이 불가능합니다 –

+0

나는 소원합니다! 필자의 경우 1850-2300 년 (DatetimeIndex는 2263 년으로 제한됨)부터 360 일 및 다른 변형과 같은 다른 달력을 사용하므로 PeriodIndex도 작동하지 않습니다. 이 접근 방식은 몇 가지 다른 장소에서 대안으로 제안되었지만 필자의 작업에서 비슷한 색인을 생성 할 수 있어야합니다. – pbreach

+0

오, 나는 당신이 무엇을 얻고 있는지 보지 않는다. 예, 작동하지만 인덱스와 같은 세 개의 열이있는 .csv에서 데이터를로드해야하며 파일을 저장할 때마다 색인에 다시 넣어야합니다. 어쩌면 충분히 직설적 인 또 다른 방법이있을 것입니다. – pbreach

답변

1

문자열로 저장하면 즉시 문제가 될 '2' > '10'입니다. 이는 거의 확실하지 않으므로 ints를 사용하는 것이 좋습니다.

In [11]: idx = pd.IndexSlice 

In [12]: df1.loc[idx[2006:2008, 6:10, 6:11], :] 
... 

하지만이 2006 사이의 사람들을 보여줍니다 즉 다음과 같이

year = range(2006,2011) 
month = range(1,13) 
day = range(1,31) 

내가 비록 당신이 여기 pd.IndexSlice을 사용할 수 있도록한다고, 내 첫번째 생각은 그것을 사용하는 것이 었습니다 -8 및 6 월 -06 및 6-11 일 (즉, 3 * 5 * 6 = 90 일). ,

In [21]: df1.index.map(lambda x: (2006, 6, 6) < x < (2008, 10, 11)) 
Out[21]: array([False, False, False, ..., False, False, False], dtype=bool) 

In [22]: df1[df1.index.map(lambda x: (2006, 6, 6) < x < (2008, 10, 11))] 
# just the (844) rows you want 

이 참을 수 느렸다 경우 트릭 (벡터화가) 일부 부동 소수점 표현을 사용하는 것입니다 :


그래서 여기에 비 벡터화 방법이다, 그냥 튜플 비교 예 :

In [31]: df1.index.get_level_values(0).values + df1.index.get_level_values(1).values * 1e-3 + df1.index.get_level_values(2).values * 1e-6 
Out[31]: 
array([ 2006.001001, 2006.001002, 2006.001003, ..., 2010.012028, 
     2010.012029, 2010.01203 ]) 
+0

float 표현은 float 슬라이싱에 대한 일반적인 엡실론 경고와 함께 나타납니다. –

+0

지도가 작동하는 방식입니다. 내 데스크톱에서 나중에 테스트해야 할 것 같네요. – pbreach