Python pandas 데이터 확인, 정렬, 선택하는 법
데이터 준비 2단계
지난 시간에는 파이썬 pandas 사용법의 첫 번째 시리즈로 [데이터 생성, 로딩 및 저장, 색인 관리하는 법][]을 알아보았습니다. 이번 시간에는 DataFrame(데이터 프레임) 안에 들어있는 데이터를 확인하고 정렬 및 선택하는 법을 알아보겠습니다.
먼저 데이터를 확인하는 법부터 살펴보겠습니다.
확인하기(Viewing)
데이터는 크게 2가지 관점에서 확인할 수 있습니다. 하나는 데이터의 전체 그림을 파악하는 것이고, 다른 하나는 데이터의 결측치(missing values)를 확인하는 것입니다. 데이터의 전체 그림을 확인하는 일은 데이터의 처리 방향을 판단하기 위해 필요합니다. DataFrame을 이루는 전체 행과 열의 개수, 열 이름, 요약값 등을 확인하는 작업은 모두 데이터의 개요를 살펴보는 일입니다.
반면, 데이터의 결측치를 파악하는 작업은 최종 결과에 영향을 줄 수 있는 요소를 관리하는 것입니다. 결측치를 처리하는 것은 중요합니다. 결측치를 어떻게 처리하는지에 따라 최종 결과가 완전히 달라질 수 있습니다. 실습을 통해 살펴보겠습니다. 사용할 예제 DataFrame(데이터 프레임)은 다음과 같습니다.
pythondata = {'포켓몬명': ['피카츄', '파이리', '꼬부기', '잠만보'],'수면시간': [7, 5, 8, 18],'능력치': [40, 60, 80, 90],'과': ['이과', '문과', '이과', '문과']}df = pd.DataFrame(data).set_index('포켓몬명') # 행 색인명 지정df
위 DataFrame 처럼 자료가 적으면 DataFrame의 모든 행이 출력됩니다. 그러나 DataFrame이 60행을 넘기면 첫 부분과 끝 부분에서 각각 5행씩 총 10행만 보입니다. 또, 20열을 넘으면 좌우로 10열씩 총 20열만 나타납니다. 중간의 데이터는 생략되어 표시되지 않습니다. 만일 행과 열을 생략하지 않고 모두 출력하고 싶다면 다음과 같은 옵션을 고려할 수 있습니다. pythonpd.set_option('display.max_rows', None) # DataFrame의 모든 행 출력pd.set_option('display.max_columns', None) # DataFrame의 모든 열 출력만일 위 설정을 되돌리고 싶다면
pd.reset_option()
패키지 함수를 사용하면 됩니다. pythonpd.reset_option('display.max_rows') # 행 출력 제한 기본값으로 되돌리기pd.reset_option('display.max_columns') # 열 출력 제한 기본값으로 되돌리기pd.reset_option('all') # 행 및 열 출력 제한 모두 기본값으로 되돌리기
모든 속성(attribute)과 메서드(method)는 pandas.DataFrame
클래스에 속합니다. 속성은 변수가 지니고 있는 값을 의미합니다. 메서드는 변수가 지니고 있는 함수입니다. 괄호가 없으면 속성, 괄호가 있으면 메서드라고 생각하면 됩니다.
1) 자료구조: type
변수의 자료구조를 알고 싶다면 type
함수를 이용하면 됩니다.
pythontype(df)# 결과pandas.core.frame.DataFrame
2) 생김새: shape, head, tail, sample
shape
속성 및 head
, tail
, sample
메서드를 이용하면 데이터의 생김새를 확인할 수 있습니다. 각 메서드는 순서대로 데이터의 행과 열의 개수, 데이터의 첫 부분, 데이터의 끝 부분, 그리고 무작위로 뽑은 데이터를 출력합니다.
개수: shape
shape
속성은 데이터의 전체 행과 열의 개수를 알려줍니다.
pythondf.shape# 결과(4, 3) # 4개 행과 3개 열: 4개의 데이터 레코드와 3개의 속성
첫 부분: head
head
속성/메서드는 데이터의 첫 5개 행만 출력합니다.
pythondf.head# 또는df.head() # 1행부터 5행까지 총 5개 행 출력
출력할 행의 개수를 지정하고 싶다면 원하는 행의 개수를 head
메서드에 인자로 전달하면 됩니다.
pythondf.head(2) # 1행부터 2행까지 총 2개 행 출력
끝 부분: tail
head
메서드와 반대로 tail
메서드는 데이터의 끝에서부터 총 5개 행을 출력합니다. tail
함수 역시 인자로 출력할 행의 개수를 지정할 수 있습니다.
pythondf.tail# 또는df.tail() # 맨 마지막 행부터 총 5개 행 출력df.tail(7) # 맨 마지막 행부터 총 7개 행 출력
무작위: sample
sample
함수는 데이터에서 임의의 n개의 행 또는 열을 무작위로 추출합니다. 이 함수는 무작위표본추출(random sampling)을 하고 싶을 때 사용됩니다.
pythondf.sample() # 임의의 1개 행 추출df.sample(n=3) # 임의의 3개 행 추출df.sample(n=1, axis=1) # 임의의 1개 열 추출df.sample(frac=0.2) # 원본 데이터의 20%만큼 비복원추출df.sample(frac=0.3, replace=True) # 원본 데이터의 30% 만큼 복원추출df.sample(frac=1.5, replace=True) # 원본 데이터의 1.5배 만큼 복원추출df.sample(n=2, weights='열1') # '열1'에서 값이 가장 큰 순서대로 2개 행 추출df.sample(n=4, random_state=1) # 임의의 4개 행 추출, random_state로 숫자를 지정해 동일 결과 재추출 가능
3) 정보: info
info
메서드는 DataFrame의 정보를 알려줍니다.
pythondf.info()# 결과<class 'pandas.core.frame.DataFrame'>Index: 4 entries, 피카츄 to 잠만보Data columns (total 3 columns):# Column Non-Null Count Dtype--- ------ -------------- -----0 수면시간 4 non-null int641 능력치 4 non-null int642 과 4 non-null objectdtypes: int64(2), object(1)memory usage: 128.0+ bytes
4) 요약 통계값: describe
describe
메서드는 DataFrame에서 수치로된 자료에 대한 요약 통계값을 알려줍니다. 결측치는 제외되고 계산됩니다. pandas에서 기술통계량을 계산할 때는 누락된 데이터를 배제하고 처리합니다.
pythondf.describe()# 결과수면시간 능력치count 4.000000 4.000000 # 빈도mean 9.500000 67.500000 # 평균std 5.802298 22.173558 # 표준편차min 5.000000 40.000000 # 최솟값25% 6.500000 55.000000 # 제1사분위수50% 7.500000 70.000000 # 제2사분위수75% 10.500000 82.500000 # 제3사분위수max 18.000000 90.000000 # 최댓값
만일 문자로 된 변수의 요약 통계값도 함께 출력하려면 해당 함수에 include='all'
옵션을 주면 됩니다. 이 옵션을 사용하면 문자로 된 변수의 빈도와 고유값의 빈도 및 최빈값과 최빈값의 빈도를 파악할 수 있습니다. 각 통계량은 각각 count
, unique
, top
, freq
라는 변수명으로 출력됩니다.
pythondf.describe(include='all')
요약 통계와 관련한 다른 메서드는 이 시리즈의 마지막 편인 Python pandas 데이터 재형성, 연산, 집계하는 법에서 자세히 살펴보도록 하겠습니다.
5) 값: values
values
속성은 DataFrame에 담긴 값을 알고 싶을 때 사용합니다.
pythondf.values# 결과array([[7, 40, '이과'],[5, 60, '문과'],[8, 80, '이과'],[18, 90, '문과']], dtype=object)
참고로 색인은 index
속성으로 확인할 수 있습니다. 색인 관리에 대한 자세한 내용은 Python pandas 데이터 생성, 로딩과 저장, 색인 관리하는 법을 참조해주세요.
pythondf.index
6) 결측치: isnull, notnull
isnull
과 notnull
은 누락된 데이터를 찾을 때 사용합니다.
isnull
isnull
은 누락된 데이터가 있는지를 확인하는 함수입니다. 누락된 값이 없으면 False
를 반환합니다.
pythonpd.isnull(df)# 결과수면시간 능력치 과포켓몬명피카츄 False False False파이리 False False False꼬부기 False False False잠만보 False False False
DataFrame에서 결측값의 총 개수를 알고 싶다면 isnull().sum()
을 사용하면 됩니다.
pythondf.isnull().sum()# 결과수면시간 0능력치 0과 0dtype: int64
notnull
notnull
은 isnull
과 반대로 누락된 데이터가 없는지를 확인합니다. 누락된 값이 없으면 "True" 값을 반환합니다.
pythonpd.notnull(df)#결과수면시간 능력치 과포켓몬명피카츄 True True True파이리 True True True꼬부기 True True True잠만보 True True True
여기서는 결측치를 확인하는 법만 살펴보았습니다. 결측치를 처리하는 작업은 Python pandas 데이터 병합, 정제, 변형하는 법에서 자세히 다루도록 하겠습니다. 지금까지 데이터를 확인하는 법을 알아보았습니다. 이번에는 데이터를 정렬하는 법을 알아보겠습니다.
정렬하기(Aligning)
데이터를 정렬하면 분류가 쉬워집니다. 정리가 잘된 데이터는 분석의 효율성을 높입니다.
데이터를 정렬하는 방법은 2가지가 있습니다. 하나는 데이터를 값의 크기에 따라 정렬하는 것이고 다른 하나는 순위를 매겨서 정렬하는 것입니다. 색인 정렬은 Python pandas 데이터 생성, 로딩과 저장, 색인 관리하는 법의 '색인 관리' 부분을 참조해주세요.
1) 값: sort_values
값의 크기에 따라 자료를 정렬하고 싶다면 sort_values
메서드를 사용하면 됩니다. 값은 기본적으로 오름차순으로 정렬됩니다.
열 개수
1개 열
다음은 열 1개에 따라 데이터를 정렬하는 코드입니다.
pythondf.sort_values('수면시간')# 또는df.sort_values(by='수면시간') # 열 이름이 '수면시간'인 열의 원소 크기에 따라 오름차순 정렬# 결과수면시간 능력치 과포켓몬명파이리 5 60 문과피카츄 7 40 이과꼬부기 8 80 이과잠만보 18 90 문과
만약 자료가 수치가 아니라 문자라면 알파벳 A-Z순으로 정렬됩니다.
2개 열 이상
여러 개의 열을 정렬하려면 열 이름이 담긴 리스트를 전달하면 됩니다.
pythondf.sort_values(by=['능력치', '수면시간']) # 열 이름을 기준으로 오름차순 정렬# 결과수면시간 능력치 과포켓몬명피카츄 7 40 이과파이리 5 60 문과꼬부기 8 80 이과잠만보 18 90 문과
정렬 방법
자료를 내림차순으로 정렬하고 싶다면 ascending
옵션에 False 값을 주면 됩니다. 열마다 정렬 옵션을 다르게 하고 싶다면 ascending
매개변수에 불리언 리스트를 전달하면 됩니다.
python# 과를 기준으로 오름차순으로 정렬한 다음 수면시간을 기준으로 내림차순 정렬df.sort_values(['과', '수면시간'],ascending=[True, False])
정렬할 때 비어있는 값이 있다면 누락값은 가장 마지막에 위치합니다.
2) 순위: rank
자료에 순위를 매겨서 정렬하고 싶다면 rank
메서드를 사용하면 됩니다.
열별 순위
rank
메서드는 열별로 순위를 매깁니다. 각 열은 독립적이고 같은 열 내부에서 순위를 매기는 것입니다.
pythondf.rank()# 결과수면시간 능력치 과포켓몬명피카츄 2.0 1.0 3.5파이리 1.0 2.0 1.5꼬부기 3.0 3.0 3.5잠만보 4.0 4.0 1.5
행별 순위
axis=1
옵션을 주면 같은 행에서 순위를 매깁니다.
pythondf.rank(axis=1)# 결과수면시간 능력치포켓몬명피카츄 1.0 2.0파이리 1.0 2.0꼬부기 1.0 2.0잠만보 1.0 2.0
순위는 기본적으로 오름차순으로 매겨집니다. 내림차순으로 순위를 매길 수도 있습니다.
내림차순 순위
내림차순으로 순위를 매기고 싶다면 ascending=False
옵션을 지정하면 됩니다.
pythondf.rank(ascending=False)# 결과수면시간 능력치 과포켓몬명피카츄 3.0 4.0 1.5파이리 4.0 3.0 3.5꼬부기 2.0 2.0 1.5잠만보 1.0 1.0 3.5
rank
의 기본 옵션은 method=average
입니다. 이 옵션은 동점 관측치에 대해서 평균 순위를 부여합니다. 동률 처리 메서드의 다른 옵션으로는 먼저 나타난 값에 순위 부여하기, 최소 순위 부여하기, 최대 순위 부여하기, 순위 간 차이를 1씩 증가하도록 설정하는 옵션이 있습니다. 어떤 옵션을 주느냐에 따라 같은 관측치라도 다른 순위를 가질 수 있습니다. 상황별로 사용할 수 있는 옵션은 다음과 같습니다.
- 동점인 값에 대해 먼저 나타난 관측치에 높은 순위를 매기려면? method='first'
- 동점인 값에 대해 최소 순위를 매기려면? method='min'
- 동점인 값에 대해 최대 순위를 매기려면? method='max'
- 순위를 1씩 증가하게 하려면? method='dense'
지금까지 데이터를 값의 크기에 따라 정렬하고 순위를 매기는 법을 알아보았습니다. 지금부터는 데이터를 선택하는 법을 살펴보겠습니다.
선택하기(Selecting)
데이터를 선택하는 일은 자원을 집중할 곳을 찾는 일입니다.
데이터를 선택하는 방법에는 인덱싱(indexing)과 슬라이싱(slicing)이 있습니다. 인덱싱은 특정 색인에 맵핑(mapping)된 값을 가져오는 작업입니다. 슬라이싱은 특정 색인 사이에 맵핑된 값을 가져오는 작업입니다. 먼저 대괄호를 이용해 데이터를 선택해보겠습니다.
1) 대괄호 []
대괄호를 이용해 데이터를 선택할 때는 라벨 색인(label index)과 정수 색인(integer index)을 이용할 수 있습니다.
라벨 색인
라벨 색인을 이용하면 특정 열을 선택할 수 있습니다. 라벨 색인을 사용하는 방법은 사전 형식과 속성 형식으로 접근하는 방법으로 나뉩니다.
pythondf['수면시간'] # 사전 형식 표기법: Series로 추출df.수면시간 # 속성 형식 표기법: Series로 추출# 결과포켓몬명피카츄 7파이리 5꼬부기 8잠만보 18Name: 수면시간, dtype: int64
위 방법은 데이터를 Series 형태로 가져옵니다. 만일 DataFrame 구조를 그대로 유지하고 싶다면 열 이름을 대괄호로 한 번 더 감싸주면 됩니다.
pythondf[['수면시간']] # DataFrame으로 추출
만일 특정 열에 있는 특정 인덱스에 해당하는 값을 알고 싶다면 아래와 같이 대괄호를 연이어 사용하면 됩니다.
pythondf['수면시간']['꼬부기'] # 꼬부기의 수면시간 추출하기# 결과8
자료를 df['열이름']
형식으로 선택하는 것은 언제나 가능합니다. 하지만 df.열이름
방식으로 열을 가져오려면 열이름이 파이썬에서 사용 가능한 형식이어야 합니다.
만일 여러 개의 열을 가져오고 싶다면 리스트를 대괄호로 한 번 더 감싸주면 됩니다.
pythondf[['수면시간', '능력치']] # 여러 변수 추출하기# 결과수면시간 능력치포켓몬명피카츄 7 40파이리 5 60꼬부기 8 80잠만보 18 90
pythondf['능력치'][['피카츄', '꼬부기']]# 결과포켓몬명피카츄 40꼬부기 80Name: 능력치, dtype: int64
아래와 같이 특정 값을 선택해 새로운 값으로 변경할 수도 있습니다.
pythondf['수면시간']['피카츄', '잠만보'] = 5# 결과수면시간 능력치 과포켓몬명피카츄 5 40 이과 # 7에서 5로 변경됨파이리 5 60 문과꼬부기 8 80 이과잠만보 5 90 문과 # 18에서 5로 변경됨
이번에는 정수 색인을 이용해서 데이터를 선택하는 법을 알아보겠습니다.
정수 색인
pythondf.columns[0] # 0번째 열이름 가져오기# 결과'수면시간'
pythondf[df.columns[0]] # 첫 번째 열 전체 가져오기# 결과포켓몬명피카츄 7파이리 5꼬부기 8잠만보 18Name: 수면시간, dtype: int64
pythondf[df.columns[-1]] # 마지막 열 전체 가져오기# 결과포켓몬명피카츄 이과파이리 문과꼬부기 이과잠만보 문과Name: 과, dtype: object
혼합
다음과 같이 정수 색인과 라벨 색인을 모두 사용해서 데이터를 선택할 수도 있습니다.
pythondf['수면시간'][3] # 잠만보 수면시간# 결과18
지금까지 대괄호를 이용해 데이터를 선택하는 법을 알아보았습니다. 이번에는 슬라이싱을 통해 원하는 범위 사이에 위치한 값을 선택하는 법을 알아보겠습니다.
2) 쌍점(:)
슬라이싱을 할 때는 쌍점(colons)을 사용합니다. 슬라이싱 역시 인덱싱처럼 라벨 색인과 정수 색인을 이용해 데이터를 선택할 수 있습니다.
라벨 색인
라벨 이름으로 슬라이싱하면 시작 색인과 끝 색인에 맵핑된 값을 모두 포함해서 출력합니다.
pythondf['수면시간']['피카츄':'꼬부기']# 결과포켓몬명피카츄 7파이리 5꼬부기 8Name: 수면시간, dtype: int64
정수 색인
반면 정수 색인 슬라이싱에서는 첫 번째 인덱스에 맵핑된 값은 선택하지만 마지막 정수에 맵핑된 값은 선택하지 않습니다.
pythondf['수면시간'][1:3] # 1행부터 2행까지 가져오기# 결과포켓몬명파이리 5꼬부기 8Name: 수면시간, dtype: int64
pythondf['수면시간'][:2]# 결과포켓몬명피카츄 7파이리 5Name: 수면시간, dtype: int64
3) loc
loc
속성을 이용하면 라벨 색인을 통해 행에 접근할 수 있습니다.
pythondf.loc['잠만보'] # 행색인 '잠만보'에 해당하는 열 반환# 결과수면시간 18능력치 90Name: 잠만보, dtype: int64
아래 코드도 위 코드와 동일한 결과를 반환합니다.
pythondf.loc['잠만보', ['수면시간', '능력치']]# 결과수면시간 18능력치 90Name: 잠만보, dtype: object
이번에는 슬라이싱을 해보겠습니다.
pythondf.loc[:'꼬부기', '능력치'] # 꼬부기까지 포함# 결과포켓몬명피카츄 40파이리 60꼬부기 80Name: 능력치, dtype: int64
4) iloc
iloc
는 정수 색인을 사용해 특정 값에 접근하는 방법입니다.
pythondf.iloc[2] # 3번째 행 꼬부기 정보 가져오기# 결과수면시간 8능력치 80Name: 꼬부기, dtype: int64
정수 색인으로 다수의 행과 열을 선택하려면 다음 코드를 사용하면 됩니다.
pythondf.iloc[2, [1, 0]]# 결과능력치 80수면시간 8Name: 꼬부기, dtype: int64
pythondf.iloc[[1, 3], [0, 1]]# 결과수면시간 능력치포켓몬명파이리 5 60잠만보 18 90
pythondf.iloc[1:3, 0:2]# 결과수면시간 능력치포켓몬명파이리 5 60꼬부기 8 80
5) 조건
특정 조건에 해당하는 데이터만 선택할 수도 있습니다. 먼저 조건이 1개인 경우를 살펴보겠습니다.
조건 1개
대괄호 []
pythondf['수면시간'] >= 7 # 수면시간이 7시간 이상인 데이터 가져오기# 결과포켓몬명피카츄 True파이리 False꼬부기 True잠만보 TrueName: 수면시간, dtype: bool
이 조건을 DataFrame에서 데이터를 선택하는 필터(filter)처럼 사용할 수도 있습니다.
pythonfilt = (df['수면시간'] >= 7)df[filt]# 또는df[df['수면시간'] >= 7]# 결과수면시간 능력치 과포켓몬명피카츄 7 40 이과꼬부기 8 80 이과잠만보 18 90 문과
만약 특정 조건에 해당하지 않는 데이터를 선택하고 싶다면 물결 기호(~)를 사용하시면 됩니다.
pythonfilt = (df['수면시간'] >= 7)df[~filt] # 수면시간이 7시간 미만인 데이터 가져오기# 결과수면시간 능력치 과포켓몬명파이리 5 60 문과
loc
loc
를 사용해서 조건에 따라 데이터를 선택할 수도 있습니다.
pythondf.loc[df['수면시간'] > 7, '능력치'] # 1개 열 가져오기# 수면시간이 7시간 초과인 행들 중 열 이름이 능력치인 데이터 가져오기# 결과포켓몬명꼬부기 80잠만보 90Name: 능력치, dtype: int64df.loc[df['수면시간'] > 7, ['능력치', '과']] # 2개 열 가져오기# 수면시간이 7시간 초과인 데이터 중 열 이름이 능력치와 과인 데이터 가져오기# 결과능력치 과포켓몬명꼬부기 80 이과잠만보 90 문과
iloc
iloc
를 사용할 수도 있습니다.
pythondf.iloc[:, :2][df['수면시간'] > 7]# 결과수면시간 능력치포켓몬명꼬부기 8 80잠만보 18 90
query
query
메서드를 사용해서 특정 조건에 해당하는 데이터를 추출할 수도 있습니다.
pythondf.query('과 == "이과"') # 과가 이과인 데이터만 선택# 또는df.query('과 != "이과"') # 과가 이과가 아닌 데이터만 선택
조건을 외부 변수에 할당한다면 query
메서드의 변수명 앞에 @
기호를 붙이면 됩니다.
pythoncondition = '이과'df.query('과 == @condition')
먼저 특정 행을 추출한 다음 특정 변수의 값을 알고 싶다면 query()
함수와 대괄호를 조합해서 사용하면 됩니다.
pythondf.query("과 == '이과'")['수면시간'] # 열 이름이 과인 데이터에서 값이 이과인 데이터들의 수면시간 데이터 추출
특정 행만 선별한 뒤 2개 이상의 열에 대한 데이터를 가져오고 싶을 때는 query()
함수와 이중 대괄호를 사용하면 됩니다.
pythondf.query("과 == '이과'")[['수면시간', '능력치']] # 열 이름이 과인 데이터에서 값이 이과인 데이터들의 수면시간과 능력치 데이터 추출
groupby의 get_group
groupby
의 get_group
메서드를 사용해도 동일한 결과를 얻을 수 있습니다.
pythondf.groupby('과').get_group('이과') # 가 이과인 데이터만 선택
groupby
함수의 사용 방법은 Python pandas 데이터 재형성, 연산, 집계하는 법을 참조해주세요. 이번에는 조건이 2개 이상인 경우를 살펴보겠습니다.
조건 2개 이상
먼저 조건이 2개 이상일 경우는 n개의 조건을 모두 만족시키는 '그리고(&)'인 경우와 n개 조건 중 하나만 만족시켜도 되는 '또는(|)'인 경우가 있습니다.
그리고(AND): &
'&' 기호는 양 조건을 모두 만족시키는 데이터를 선택하고 싶을 때 사용합니다.
pythondf.loc[(df['수면시간'] > 7) & (df['과'] == '이과')]# 또는df.query('수면시간 > 7 & 과 == "이과"')# 결과수면시간 능력치 과포켓몬명꼬부기 8 80 이과
또는(OR)
'|'
'|' 기호는 양 조건 중에 한 조건만 만족시켜도 되는 데이터를 선택하고 싶을 때 사용합니다.
pythondf.loc[(df['수면시간'] > 7) | (df['과'] == '이과')]# 또는df.query('수면시간 > 7 | 과 == "이과"')# 결과수면시간 능력치 과포켓몬명피카츄 7 40 이과꼬부기 8 80 이과잠만보 18 90 문과
만일 여러 개의 |
기호를 사용해서 코드가 길어지면 isin
메서드를 이용해 코드 길이를 줄일 수 있습니다.
isin
isin
메서드는 특정 값에 대한 포함 여부를 불리언값으로 반환합니다.
pythonresult = df['과'].isin(['이과', '감자']) # '과' 열의 값으로 '이과' 또는 '감자'가 있는지를 확인result# 결과포켓몬명피카츄 True파이리 False꼬부기 True잠만보 FalseName: 과, dtype: bool
여기서 isin
메서드를 아래와 같이 필터로 사용하면 원하는 값만을 포함한 데이터를 추출할 수 있습니다.
pythonfilt = df['과'].isin(['이과', '감자']) # '과'가 '이과' 또는 '감자'인 포켓몬df[filt] # filt를 조건 필터로 사용# 결과수면시간 능력치 과포켓몬명피카츄 7 40 이과꼬부기 8 80 이과
query + is
query()
에 is
메서드를 사용해도 위와 동일한 결과를 얻을 수 있습니다.
pythondf.query('과 in ["이과", "감자"]')
get_indexer
Index.get_indexer
메서드를 이용하면 여러 값이 들어 있는 배열에서 유일한 값의 색인 배열을 구할 수 있습니다.
pythonto_match = pd.Series(['셀러리', '고구마', '호박', '고구마', '감자', '고구마'])unique_values = pd.Series(to_match.unique()) # 셀러리, 고구마, 호박, 감자 순pd.Index(unique_values).get_indexer(to_match)# 결과array([0, 1, 2, 1, 3, 1], dtype=int64)
6) 문자열: startswith, endswith, contains
특정 문자열로 시작하는 데이터를 선택하고 싶으면 startswith
, 특정 문자열로 끝나는 데이터를 선택하고 싶으면 endswith
를 사용하면 됩니다.
시작: startswith
pythonfilt = df['과'].str.startswith('이') # '이'로 시작df[filt]# 결과수면시간 능력치 과포켓몬명피카츄 7 40 이과꼬부기 8 80 이과
끝: endswith
pythonfilt = df['과'].str.endswith('능') # 예체능에서 '능'으로 끝남df[filt]# 결과없음
포함: contains
특정 문자열을 포함하는 데이터를 선택하고 싶다면 contains
메서드를 사용하면 됩니다.
pythondf['과'].str.contains('문')# 결과포켓몬명피카츄 False파이리 True꼬부기 False잠만보 TrueName: 과, dtype: bool
전체 데이터를 가져오려면 다음과 같이 사용하면 됩니다.
pythonfilt = df['과'].str.contains('문') # '문' 포함df[filt]# 결과수면시간 능력치 과포켓몬명파이리 5 60 문과잠만보 18 90 문과
pythonfilt = df['과'].str.contains('문') # '문' 포함df[~filt] # '과'에 '문'이 들어가는 데이터 제외# 결과수면시간 능력치 과포켓몬명피카츄 7 40 이과꼬부기 8 80 이과
만일 NaN
으로 된 데이터가 있다면 na
파라미터를 이용해 해당 데이터를 제외할 수 있습니다.
pythonfilt = df['과'].str.contains('문', na=False) # NaN으로 된 데이터를 False로 처리df[~filt]
7) 유일값: unique, nunique
데이터에서 고유한 값을 알고 싶다면 unique
또는 nunique
를 사용할 수 있습니다. 전자는 유일값의 종류를 후자는 유일값의 개수를 알려줍니다.
종류
unique
메서드는 열에서 중복되는 값을 제거하고 유일값만 담고 있는 Series를 반환합니다.
pythondf['과'].unique()# 결과array(['이과', '문과'], dtype=object)
유일값은 정렬된 순서로 반환되지 않습니다. 만약 값을 정렬하고 싶다면 유일값을 추출해 변수에 할당한 뒤에 sort()
함수를 사용해야 합니다.
pythonuniques = df['과'].unique()uniques.sort()uniques# 결과array(['문과', '이과'], dtype=object)
개수
nunique
메서드는 데이터의 고유한 값의 개수를 알고 싶을 때 사용합니다.
pythondf['과'].nunique()# 결과2
8) 빈도수: value_counts
value_counts
메서드는 유일 범주별 빈도(frequency)를 계산하여 빈도표(frequency table)를 Series 객체로 반환해줍니다. 도수는 값의 크기에 따라 내림차순으로 정렬됩니다.
기본
pythondf['과'].value_counts()df['과']# 결과이과 2문과 2Name: 과, dtype: int64
pythonpd.value_counts(df['과'].values, sort=False)# 결과이과 2문과 2dtype: int64
만일 인덱스를 알파벳 순으로 정렬하고 싶다면 df.value_counts()
에 sort_index()
를 사용하면 됩니다.
pythondf['과'] = df['과'].value_counts().sort_index()df['과']# 결과문과 2이과 2Name: 과, dtype: int64
비율
만약 각 유일값의 도수가 전체에서 차지하는 비율, 즉 상대빈도(relative frequency)를 알고 싶다면 normalize=True
옵션을 주면 됩니다.
pythondf['과'].value_counts(normalize=True)# 결과이과 0.5문과 0.5Name: 과, dtype: float64
히스토그램
DataFrame의 여러 열에 대해 히스토그램(histogram)을 구하고 싶으면 apply
함수에 pd.value_counts
를 넘기면 됩니다.
pythondf2 = pd.DataFrame({'1분기': [5, 3, 4, 1, 2],'2분기': [2, 3, 5, 1, 3],'3분기': [4, 1, 5, 2, 1]})result = df2.apply(pd.value_counts).fillna(0)# 결과1분기 2분기 3분기1 1 1.0 2.02 1 1.0 1.03 1 2.0 0.04 1 0.0 1.05 1 1.0 1.0
위 결과의 행 라벨(1, 2, 3, 4, 5)은 유일 범주입니다. 행 라벨은 각 열에서 해당 값이 몇 번 나타났는지 알려줍니다. apply
함수의 사용법은 Python pandas 데이터 재형성, 연산, 집계하는 법을 참조해주세요.
9) 그룹별 순서: groupby + cumcount
만약 같은 값끼리 그룹별로 묶어서 각 그룹 내에서 해당 값의 순서를 구하고 싶다면 Python pandas 데이터 재형성, 연산, 집계하는 법에서 다룰 groupby
함수와 cumcount
함수를 이용하면 됩니다.
pythondf_group = pd.DataFrame(list("aaaba"), columns=['열이름'])df_group.groupby('열이름').cumcount()# 결과0 0 # a1 1 # a2 2 # a3 0 # b4 3 # adtype: int64
지금까지 Python pandas 데이터 프레임에서 데이터를 확인하는 법, 데이터를 정렬하는 법, 마지막으로 데이터를 선택하는 다양항 방법을 알아보았습니다. 다음 편에서는 Python pandas 데이터 병합, 정제, 변형하는 법을 살펴보겠습니다. 모두 수고 많으셨습니다.
참고 문헌
- [1] 김영우, 『Do it! 쉽게 배우는 파이썬 데이터 분석』, 김영근, 한빛미디어. 2022.
- [2] 유튜브(나도코딩). (2021.10.05). 파이썬 코딩 무료 강의 (활용편5) - 데이터 분석 및 시각화, 이 영상 하나로 끝내세요 [비디오파일]. 검색경로 https://www.youtube.com/watch?v=PjhlUzp_cU0
- [3] 웨스 맥키니, 『파이썬 라이브러리를 활용한 데이터 분석』, 김영근, 한빛미디어. 2019, 203-207, 220-224.
- [4] Clary K, 「[파이썬] 판다스(pandas) sample 함수로 데이터프레임 자유자재 샘플링하기」, 네이버 블로그, "https://blog.naver.com/PostView.nhn?blogId=youji4ever&logNo=221961031855"
- [5] GeeksforGeeks, 「Indexing and Selecting Data with Pandas」, GeeksforGeeks, "https://www.geeksforgeeks.org/indexing-and-selecting-data-with-pandas/"
- [6] Manu Sharma, 「Pandas Index Explained」, Towards Data Science, "https://towardsdatascience.com/pandas-index-explained-b131beaf6f7b"