Pandas에서 MultiIndex 인덱스 열 값을 쿼리하는 방법
코드 예 :
In [171]: A = np.array([1.1, 1.1, 3.3, 3.3, 5.5, 6.6])
In [172]: B = np.array([111, 222, 222, 333, 333, 777])
In [173]: C = randint(10, 99, 6)
In [174]: df = pd.DataFrame(zip(A, B, C), columns=['A', 'B', 'C'])
In [175]: df.set_index(['A', 'B'], inplace=True)
In [176]: df
Out[176]:
C
A B
1.1 111 20
222 31
3.3 222 24
333 65
5.5 333 22
6.6 777 74
이제 A 값을 검색하려고합니다.
Q1 : 범위 [3.3, 6.6]-예상 반환 값 : [3.3, 5.5, 6.6] 또는 마지막 포함 인 경우 [3.3, 3.3, 5.5, 6.6] 및 [3.3, 5.5 ] 또는 [3.3, 3.3, 5.5].
Q2 : 범위 [2.0, 4.0]-예상 반환 값 : [3.3] 또는 [3.3, 3.3]
다른 MultiIndex 차원에 대해 동일 합니다. 예를 들어 B 값 :
Q3 : 범위 내 데이터 행 수로 반복되는 [111, 500] 범위-예상되는 반환 값 : [111, 222, 222, 333, 333]
더 공식적인:
T가 A, B 및 C 열이있는 테이블이라고 가정하겠습니다. 테이블에는 n 개의 행이 있습니다. 테이블 셀은 숫자입니다 (예 : A double, B 및 C 정수). 테이블 T 의 DataFrame 을 만들고 이름을 DF로 지정하겠습니다. DF의 열 A 및 B 인덱스 (복제없이, 즉 인덱스로 A와 B를 분리하지 않고 데이터로 분리하지 않음), 즉이 경우 A와 B를 MultiIndex로 설정해 보겠습니다 .
질문 :
- 예를 들어, 인덱스 A (또는 B)를 쿼리하기 위해 인덱스에 쿼리를 작성하는 방법 (예 : 레이블 간격 [120.0, 540.0])? 레이블 120.0 및 540.0이 있습니다. 쿼리에 대한 응답으로 인덱스 목록에만 관심이 있음을 분명히해야합니다!
- 방법은 동일하지만 라벨의 경우 120.0 및 540.0이 존재하지 않지만 값이 120보다 낮거나 120보다 크고 540보다 작거나 540보다 큰 레이블이 있습니까?
- Q1 및 Q2에 대한 대답이 고유 한 인덱스 값인 경우 인덱스 범위의 데이터 행 수와 동일하지만 반복이 있습니다.
인덱스가 아닌 컬럼의 경우 위의 질문에 대한 답을 알고 있지만 인덱스의 경우 웹에서 오랜 연구와 pandas 의 기능을 실험 한 끝에 성공하지 못했습니다. 추가 프로그래밍이없는 유일한 방법은 인덱스 외에 데이터 열로 A와 B를 복제하는 것입니다.
질의에 DF 바이 MultiIndex의 예를 들면, 값이 여기서 (A> 1.7) 및 (B <666) :
In [536]: result_df = df.loc[(df.index.get_level_values('A') > 1.7) & (df.index.get_level_values('B') < 666)]
In [537]: result_df
Out[537]:
C
A B
3.3 222 43
333 59
5.5 333 56
따라서 예를 들어 여전히 필요한 경우 'A' 인덱스 값 을 얻으려면 :
In [538]: result_df.index.get_level_values('A')
Out[538]: Index([3.3, 3.3, 5.5], dtype=object)
문제는 대용량 데이터 프레임에서 인덱스 선택 별 성능이 정렬 된 일반 행 선택보다 10 % 더 나쁘다는 것입니다. 그리고 반복적 인 작업, 루핑에서 지연이 누적되었습니다. 예를보십시오 :
In [558]: df = store.select(STORE_EXTENT_BURSTS_DF_KEY)
In [559]: len(df)
Out[559]: 12857
In [560]: df.sort(inplace=True)
In [561]: df_without_index = df.reset_index()
In [562]: %timeit df.loc[(df.index.get_level_values('END_TIME') > 358200) & (df.index.get_level_values('START_TIME') < 361680)]
1000 loops, best of 3: 562 µs per loop
In [563]: %timeit df_without_index[(df_without_index.END_TIME > 358200) & (df_without_index.START_TIME < 361680)]
1000 loops, best of 3: 507 µs per loop
가독성을 위해 , 우리는 간단하게 사용할 수 있습니다 방법을 긴 피하기 위해, 및 / 에 이리저리합니다.query()
df.index.get_level_values()
reset_index
set_index
대상은 다음과 같습니다 DataFrame
.
In [12]: df
Out[12]:
C
A B
1.1 111 68
222 40
3.3 222 20
333 11
5.5 333 80
6.6 777 51
Q1에 대한 답변 ( A
범위 내 [3.3, 6.6]
) :
In [13]: df.query('3.3 <= A <= 6.6') # for closed interval
Out[13]:
C
A B
3.3 222 20
333 11
5.5 333 80
6.6 777 51
In [14]: df.query('3.3 < A < 6.6') # for open interval
Out[14]:
C
A B
5.5 333 80
물론 <, <=, >, >=
어떤 종류의 포함 을 위해 놀 수 있습니다 .
마찬가지로 Q2에 대한 답변 ( A
범위 내 [2.0, 4.0]
) :
In [15]: df.query('2.0 <= A <= 4.0')
Out[15]:
C
A B
3.3 222 20
333 11
Answer for Q3 (B
in range [111, 500]
):
In [16]: df.query('111 <= B <= 500')
Out[16]:
C
A B
1.1 111 68
222 40
3.3 222 20
333 11
5.5 333 80
And moreover, you can COMBINE the query for col A
and B
very naturally!
In [17]: df.query('0 < A < 4 and 150 < B < 400')
Out[17]:
C
A B
1.1 222 40
3.3 222 20
333 11
With a 'float' like index you always want to use it as a column rather than a direct indexing action. These will all work whether the endpoints exist or not.
In [11]: df
Out[11]:
C
A B
1.1 111 81
222 45
3.3 222 98
333 13
5.5 333 89
6.6 777 98
In [12]: x = df.reset_index()
Q1
In [13]: x.loc[(x.A>=3.3)&(x.A<=6.6)]
Out[13]:
A B C
2 3.3 222 98
3 3.3 333 13
4 5.5 333 89
5 6.6 777 98
Q2
In [14]: x.loc[(x.A>=2.0)&(x.A<=4.0)]
Out[14]:
A B C
2 3.3 222 98
3 3.3 333 13
Q3
In [15]: x.loc[(x.B>=111.0)&(x.B<=500.0)]
Out[15]:
A B C
0 1.1 111 81
1 1.1 222 45
2 3.3 222 98
3 3.3 333 13
4 5.5 333 89
If you want the indices back, just set them. This is a cheap operation.
In [16]: x.loc[(x.B>=111.0)&(x.B<=500.0)].set_index(['A','B'])
Out[16]:
C
A B
1.1 111 81
222 45
3.3 222 98
333 13
5.5 333 89
If you REALLY want the actual index values
In [5]: x.loc[(x.B>=111.0)&(x.B<=500.0)].set_index(['A','B']).index
Out[5]:
MultiIndex
[(1.1, 111), (1.1, 222), (3.3, 222), (3.3, 333), (5.5, 333)]
ReferenceURL : https://stackoverflow.com/questions/17921010/how-to-query-multiindex-index-columns-values-in-pandas
'programing' 카테고리의 다른 글
BASH에서 "CLS"와 동일합니까? (0) | 2021.01.14 |
---|---|
getSupportFragmentManager ()가 정의되지 않았습니다. (0) | 2021.01.14 |
Windows 용 Linux에서 Qt 5 빌드 (0) | 2021.01.14 |
Java 예외에 대해 가능한 한 많은 정보를 기록하는 방법은 무엇입니까? (0) | 2021.01.14 |
Net.Reflector의 "네임 스페이스는 필드 또는 메서드와 같은 멤버를 직접 포함 할 수 없습니다." (0) | 2021.01.14 |