[Python] Pandas의 배열 참조 방법
Pandas를 배우기 전까지…
나는 데이터를 다룰 때 항상 하나씩 직접 보면서 처리하는방식에 익숙했다.
그게 디버깅을 실시간으로 하며, 정확한 코드를 짜는거라고 생각을 했으니까..
또한 내가 주로 사용했던 SQL과 JAVA에서는 배열이든 리스트든, 인덱스는 언제나 숫자였고, 그 숫자는 곧 위치를 의미했다. 특정 값을 찾고 싶다면 반복을 돌리거나 조건을 걸어 하나씩 비교하는 게 당연한 흐름이었다.
하지만 Pandas의 데이터 프레임은 처음부터 다른 접근을 요구했다.
인덱스를 라벨이라고 칭하며, 인덱싱과 슬라이싱에도
df[1:3]
, df.loc[1:3]
, df.iloc[1:3]
라는 새로운 문법들이 등장했다.
불리언 인덱싱은 그나마 감이 온다
그 와중에 좀 적응이 된 내용은 불리언 인덱싱이다.
조건을 주고, 그 조건에 맞는 행만 추려내는 방식은 마치 SQL의 WHERE
절처럼 느껴진다.
df[df['score'] > 85]
이 한 줄이 말하고자 하는 의도는 명확하다.
score가 85보다 큰 행들만 골라내라.
Pandas가 내부에서 [False, True, True]
같은 불리언 배열을 만들어 필터링한다는 걸 알고 나면,
구조도 어느 정도 납득이 간다.
다만, 여기서도 .loc
을 함께 쓰는 것이 더 안전하다는 말을 듣고 나면 또 고민이 생긴다.
“왜 .loc
을 붙여야 하지?”, “df[조건]
만으로는 부족한가?” 같은 의문이 연달아 따라온다.
loc는 왜 이렇게 생겨먹었나..
.loc
은 겉보기에 그냥 슬라이싱 문법처럼 생겼다.
df.loc[10:11]
같은 코드를 보면, 딱히 낯설 게 없어 보인다.
그런데 실제로 써보면, 이건 단순한 슬라이싱이 아니다.
loc는 어떤 값을 ‘찾는 방식 자체’가 다르다.
일반적인 인덱싱은 순서대로 값을 자른다.
슬라이싱이면 앞에서부터 몇 번째, 몇 번째까지 자른다는 흐름이 명확하다.
그런데 .loc
은 그게 아니다.
df.loc[df['score'] > 85].loc[11]
여기서 무슨 일이 일어나는가..?
- 첫 번째
.loc[df['score'] > 85]
에서 조건을 만족하는 행 전체를 필터링한다. - 그 결과가 새로운 DataFrame이 된다.
- 그 위에서 다시
.loc[11]
을 하면, 그 결과 내부의 인덱스 라벨 11을 탐색하게 된다.
한 줄짜리지만 실제로는 불리언 인덱싱 → 결과 슬라이싱 → 하위 추출이라는
세 단계가 압축돼 있는 셈이다.
이게 .loc
이 헷갈리는 진짜 이유였다.
탐색 흐름이 연속적이지 않고, 중간 결과에 따라 탐색 기준이 달라지며,
그 와중에도 문법은 너무 간단하게 생겨서 실수하기 쉽다.
숫자라서 헷갈린 게 아니다.
탐색 자체가, 사고 흐름 자체가 낯설었던 거다.
마무리..
numpy와도 마찬가지로, 내가 헷갈렸던 건 문법 그 자체보다도 사고 방식의 차이였다.
그 추상화가 처음엔 낯설고 불편했지만,
하나씩 해석해보며 익숙해지다 보니 왜 이렇게 만들었는지도 조금씩 이해가 되기 시작했다.
내가 익숙하지 않았던 건 문법이 아니라, 그 수단을 받아들이는 사고의 전환이었을지도 모른다.
Leave a comment