Data_Analysis_Track_33/Python

Python_Pandas_03(정렬, 집계)

lsc99 2023. 9. 15. 17:45

정렬

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)