Python_Pandas_03(정렬, 집계)
정렬
index이름, column 이름을 기준으로 정렬
sort_index(axis, ascending=True)
- axis
index 이름 기준 정렬(행) : 'index' 또는 0 (기본값)
column 이름 기준 정렬(열) : 'columns' 또는 1
- ascending
정렬방식
True(기본): 오름차순, False: 내림차순
- inplace
원본에 적용 여부
False(기본): 변경한 복사본 반환
True : 원본을 변경
movie_df.csv 파일 불러오기
import pandas as pd
df = pd.read_csv('saved_data/movie_df.csv', index_col = 'movie_title')
0번 컬럼 삭제
df.drop(columns = 'Unnamed: 0', inplace=True)
오름차순, 내림차순
df.sort_index() # 오름차순 정렬
df.sort_index(ascending=False) # 내림차순 정렬
컬럼 이름을 기준으로 정렬
df.sort_index(axis=1) # 컬럼 이름을 기준으로 정렬
df.sort_index(axis='columns')
df2 생성
df2 = df.sort_index()
df2
다양한 방식으로 조회해본다.
# index 이름을 정렬하고 나면 '~ 시작하는 이름'으로 조회 가능
df2.loc['A':'C'] # end는 포함안됨.
# A로 시작하는 이름 ~ C로 시작하는 이름전까지
df.sort_index().loc['A':'B'] # A로 시작하는 영화들만 조회 -> 부분적 조회 가능
# df.loc['A':'B'] # sorting된 상태에서만 가능하다.
특정 컬럼(열)의 값을 기준으로 정렬
sort_values(by, ascending, inplace)
- by
정렬 기준 컬럼이름을 문자열로 지정
여러 컬럼에 대해 정렬할 경우 리스트에 담아 전달
- ascending
정렬방식
True(기본): 오름차순, False: 내림차순
여러 컬럼에 대해 정렬할 경우 정렬방식도 리스트에 담아 전달
- inplace
원본에 적용 여부
False(기본): 변경한 복사본 반환
True : 원본을 변경
- 결측치는 방식과 상관없이 마지막에 나온다.
! 문자열 정렬기준 : 특수문자 -> 숫자 > 영문대문자 -> 영문소문자 -> 다국어문자
ex) "A" < "a" < "가"
# 행정렬 정렬기준은 컬럼의 값
# director_name을 기준으로 오름차순 행정렬
df.sort_values(by = "director_name") # by 생략 가능
df.sort_values(by = "director_name", ascending=False) # 내림차순
오름차순, 내림차순
df.sort_values(['duration', 'imdb_score'])[['duration', 'imdb_score']].head(20)
df.sort_values(['duration', 'imdb_score'], ascending=[True, False])[['duration', 'imdb_score']].head(20)
# duration : True - 오름차순, imdb_score : False - 내림차순
query
# df 처리한 결과에 대해서 정렬
result = df.query('duration > 250').sort_values("duration")
result
flights.csv (항공기 운항 기록 데이터) 으로 실습
flights.csv파일을 읽어 flight라는 DataFrame 생성
flight = pd.read_csv("data/flights.csv")
flight.shape
컬럼별 결측치 수 확인
flight.isnull().sum()
기술통계 메소드들을 이용한 데이터 집계
- DataFrame에 기술 통계 메소드들을 적용할 경우 컬럼별로 계산한다.
- sum(), mode(), max(), min(), unique(), nunique(), count()는 문자열에 적용가능하다.
idxmax(), idxmin() 는 문자열 컬럼에 사용할 수 없다. (문자열의 경우 넘파이의 argmax(), argmin() 함수를 사용한다.)
공통 매개변수
- skipna=True(기본값)
결측치(NA)를 포함해서 계산할지 여부 설정.
True가 기본값으로 결측치(NA)를 제외하고 처리한다.
결측치 제외하지 않으려면 skipna=False로 설정하는데 결측치가 있으면 결과는 결측치가 된다.
- axis
DataFrame에 적용할 때 계산방향을 설정
- 0 또는 'index' (기본값): 컬럼 방향으로 집계
- 1 또는 'columns': 행 방향으로 집계
# 최빈값
flight.mode()
최대값, 최소값, 평균
flight.max()
flight.min()
# numeric_only=True일 경우 숫자, 소수, 부울값만 있는 열에대해서만 연산을 수행.
flight.mean(numeric_only=True)
합계
flight.sum()
flight.sum(numeric_only=True)
flight[['DEP_DELAY','ARR_DELAY']].sum() # 원하는 컬럼만 선택한 후에 집계
최빈값
flight[['MONTH', 'DAY', 'WEEKDAY']].mode()
flight.select_dtypes(include='object').mode()
결측치가 있는 경우 sum
flight.sum(numeric_only=True, skipna=False)
# 결측치가 있는 경우 결과는 결측치(NaN)
컬럼별 결측치 개수 확인
flight.isnull().sum()
aggregate(func, axis=0, *args, **kwargs) 또는 agg(func, axis=0, *args, **kwargs)
- DataFrame, Series의 메소드로 집계결과를 다양한 형태로 묶어서 볼 때 사용한다.
사용자 정의 집계메소드를 사용할 때도 편리하다.
매개변수
- func
집계 함수 지정
함수명/함수리스트 (문자열)
- 판다스 제공 집계메소드들은 문자열로, 사용자정의 집계함수는 함수 객체로 전달
Dictionary : {'집계할컬럼' : 집계함수, ... }
- 컬럼별로 다른 집계를 할 경우
- axis
DataFrame에 적용할 때 0 방향으로 계산할 지 1 방향으로 계산할지 설정
- 0 또는 'index' (기본값): 컬럼 방향으로 집계
- 1 또는 'columns': 행 방향으로 집계
- *args, **kwargs
함수에 전달할 매개변수.
집계함수는 첫번째 매개변수로 Series를 받는다. 그 이외의 매개변수가 있는 경우.
# 판다스가 제공하는 집계 메소드(함수)를 사용할 경우 함수명을 문자열로 지정.
flight["ARR_DELAY"].agg(["min", "max"])
flight['ARR_DELAY'].aggregate(["mean", "std"])
flight.agg(['min', 'max']).T
flight[['DEP_DELAY', 'ARR_DELAY']].agg(['mean', 'std'])
# 수치형 -> float, int --> number
flight.select_dtypes(include='number').agg(['min', 'max', 'mean']).T
사용자 정의함수 -> 객체로 전달
# 컬럼별로 다른 집계를 계산
# ('컬럼명':'집계메소드이름')
# DEP_DELAY -> 평균, ARR_DELAY : 최소/최대 값
d = {
"DEP_DELAY":'mean',
"ARR_DELAY":['min', 'max']
}
flight.agg(d)
또 다른 사용자 정의 집계함수를 이용
# 사용자 정의 집계 함수.
# 컬럼의 최대값과 최소값 간의 차이
# 파라미터 : 집계하려는 Series (필수) -> 첫번째 파라미터(agg()메소드와 연동)
def min_max_diff(column):
'''
Series의 최소값과 최대값의 차이를 계산하는 집계함수.
[parameter]
column: pd.Series - 집계할 대상 Series
[return]
float: max - min 결과. 문자열 컬럼일 경우 None을 반환
[raise]
문자열 컬럼일 경우 XXX.exception
'''
if column.dtype == 'object' or column.dtype == 'str':
return None
return column.max() - column.min()
결과 확인
min_max_diff(flight['ARR_DELAY'])
flight['ARR_DELAY'].agg(min_max_diff)
def agg(self, func):
return func(self.data)
flight['ARR_DELAY'].agg(['min','max', min_max_diff])
Groupby
- 특정 열을 기준으로 같은 값을 가지는 행끼리 묶어서 group화 한다.
- ~~ 별 집계를 할 때 사용한다. (성별, 직급별, 등급별 ...)
Group으로 묶을 기준 열은 범주형타입(category)을 사용한다.
- 구문
DF.groupby('그룹으로묶을기준컬럼')
DataFrameGroupby 객체를 반환한다.
DataFrameGroupby 객체는 어떤 행끼리 묶여있는지 정보를 가진다. 이 객체의 집계함수를 사용하면 그룹별 집계를 할 수 있다.
DataFrameGroupby객체['집계할 컬럼'].집계함수()
groupby에 여러개의 컬럼을 기준으로 나눌 경우 리스트에 묶어서 전달한다.
집계할 컬럼이 여러개인 경우 리스트로 묶어준다.
- 집계함수
기술통계 함수들
agg()/aggregate()
- 여러 다른 집계함수 호출시(여러 집계를 같이 볼경우)
- 사용자정의 집계함수 호출시
- 컬럼별로 다른 집계함수들을 호출할 경우
컬럼 AIRLINE의 value 개수 확인
flight['AIRLINE'].value_counts()
컬럼 AIRLINE(항공사)별로 ARR_DELAY의 평균 구하기
# 항공사별 도착지연시간의 평균
flight.groupby('AIRLINE')['ARR_DELAY'].mean()
컬럼 AIRLINE(항공사)별로 숫자, 소수, 부울값만 있는 열에 대해서만(numeric) 평균 구하기
flight.groupby('AIRLINE').mean(numeric_only=True)
컬럼 AIRLINE(항공사)별로 DEP_DELAY, ARR_DELAY의 평균 구하기
# 항공사별 출발/도착 지연시간의 평균
# df.groupby()[집계할 컬럼].집계메소드
flight.groupby('AIRLINE')[['DEP_DELAY', 'ARR_DELAY']].mean()
출발 공항별 출발지연시간의 최소값, 최대값
# 출발 공항별 출발지연시간의 최소값, 최대값
flight.groupby("ORG_AIR")['DEP_DELAY'].agg(["min", "max", min_max_diff])
복수열 기준 그룹핑
- 두개 이상의 열을 그룹으로 묶을 수 있다.
- groupby의 매개변수에 그룹으로 묶을 컬럼들의 이름을 리스트로 전달한다.
# 월,요일별 도착지연시간의 평균 -> groupby로 묶을 기준컬럼이 2개이상.
result = flight.groupby(['MONTH', 'WEEKDAY'])['ARR_DELAY'].mean()
result
Group 별 집계결과에서 특정 조건의 항목만 조회
- Groupby 집계 후 boolean indexing 처리한다.
# 항공사별 (출발) 취소 건수
flight.groupby('AIRLINE')['CANCELLED'].sum()
# 취소되지 않은 것 건수
(flight['CANCELLED'] == 0).sum()
# 항공사별 (출발) 취소 건수, 100회 이상인 항공사만 조회
result = flight.groupby('AIRLINE')['CANCELLED'].sum()
result[result >= 100]
agg() 를 사용해 사용자 정의 집계 함수 호출
- DataFrame.agg(func=None, axis=0, *args, **kwargs)
axis : 사용자 정의 함수에 전달할 값들(Series)의 축 지정
- Series.agg(func=None, axis=0, *args, **kwargs)
DataFrame의 agg와 매개변수 구조를 맞추기 위해 axis 지정한다. (kwargs를 이용해 매개변수 전달할 경우 axis는 생략해도 된다. - axis기본값 0을 그냥 쓰면 되므로. - keyword 인자 뒤에 position 인자는 안되서 *args로 값 전달시에는 axis를 지정해야 한다.)
- DataFrameGroupBy.agg(func, *args, **kwargs)
axis 지정안함.
사용자 함수에 Series를 group 별로 전달한다.
- SeriesGroupBy.agg(func=None, *args, **kwargs)
axis 지정안함
사용자 함수에 Series를 group 별로 전달한다.
- *args, **kwargs는 사용자 정의 함수에 선언한 매개변수가 있을 경우 전달할 값을 전달한다.
키워드 인자를 이용해 가변인자로 전달하는 것이 편하다.
# 판다스 제공 집계함수를 agg() 이용해서 호출
flight.select_dtypes(include="int64").agg("count") # DF.agg()
flight['ARR_DELAY'].agg('count') # Series.agg()
flight.groupby('AIRLINE').agg('count') # DataFrameGroupby.agg()
flight.groupby('AIRLINE')['ARR_DELAY'].agg('count')
# 사용자 정의 집계함수 agg() 이용해서 호출
def iqr(src:"집계대상", q1=0.25, q3=0.75):
'''
IQR(Inter Quartile Range) - 4분위수에서 3분위 - 1분위
'''
# print(type(src))
qt1, qt3 = src.quantile(q = [q1, q3])
return qt3 - qt1
# DataFrame.agg(사용자정의) DataFrame의 각 컬럼(Series)들을 하나씩 사용자정의 함수에 전달
flight.select_dtypes(include="int64").agg(iqr)
flight['ARR_DELAY'].agg(iqr)
# SeriesGroupby.agg(사용자정의) : Series(컬럼)을 group별로 하나씩 사용자 정의 함수에 전달
flight.groupby("AIRLINE")["ARR_DELAY"].agg(iqr)
# 각 컬럼(Series)의 값을 group별로 하나씩 사용자 정의 함수에 전달
flight.groupby('AIRLINE')[['DEP_DELAY', 'ARR_DELAY']].agg(iqr)