Loading [MathJax]/jax/output/CommonHTML/fonts/TeX/fontdata.js

1. 5. 데이터 사전 처리

1.1. 1) 누락 데이터 처리

  • 누락 데이터 확인
    • fo() : 데이터프레임 요약 정보 - 유효한 값의 개수를 보여줌
    • valuecounts(dropna=False) : 누락 데이터 개수 확인 ( default : **dropna = True**)
    • ==isnull()== : **누락 데이터**면 True를 반환, 유요한 데이터가 존재하면 False를 반환
      • df.isνll().(aξs=0)
    • ==notnull()== : **유효한 데이터**가 존재하면 True를 반환하고, 누락 데이터면 False를 반환

 

  • 누락 데이터 제거
    • 열을 삭제하면 분석 대상이 갖는 특성(변수)를 제거
    • 행을 삭제하면 분석 대상의 관측값(레코드) 제거
    • ==dropna(thresh=500)==
# for 반복문 각 열의 NaN 개수 계산하기(묘미***)
null_df = df.isnull()

for col in null_df.columns: 
    null_count = null_df[col].value_counts() # 각 열의 NaN 개수 파악 

    try: 
        print(col, ':', null_count[True])  # NaN 값이 있으면 개수 출력
    except: 
        print(col, ':', 0)  # NaN 값이 없으면 0개 출력
# NaN 값이 500개 이상(threshold)인 열 모두 삭제

df_thresh = df.dropna(axis=1, thresh=500)
# deck 의 NaN 688 개만 적용됨 
# age 열에 나이 데이터가 없는 모든 행 삭제 
df_age = df.dropna(subset=['age'], how='any', axis=0)

 

  • 누락 데이터 치환
    • ==fillna(inplace=True)==
    • fillna()
      • place=True 옵션을 추가해야 원본 객체 변경
      • 주의해서 사용!
# age의 열의 NaN 값을 다른 나이 데이터 평균으로 변경하기 
mean_age = df['age'].mean(axis=0)   # age 열의 평균 계산 (NaN 값 제외)
df['age'].fillna(mean_age, inplace=True)

 

    • 가장 많이 출현한 값
# most_freq (비정형 데이터 : 최대빈도)
most_freq = df['embark_town'].value_counts(dropna=True).idxmax()
df_embark_town_null['embark_town'].fillna(most_freq)

 

  • fillna(method=ffill)
    • NaN이 있는 행의 직전 행에 있는 값으로 바꿔줌
    • method=bfill : 다음 행에 있는 값
df['embark_town'].fillna(method='ffill', inplace=True)
df['embark_town'][825:830]



1.2. 2) 중복 데이터 처리

  • 중복 데이터 확인 : ==duplicated()==
    • duplicated()
    • 행의 레코드가 중복되는지 여부
    • 중복되는 행이면 True, 처음 나오는 행은 False
df_dup = df.duplicated()

 

  • 중복 데이터 제거 : ==drop_duplicates()==
    • 중복되는 행을 제거하고 고유한 관측값을 가진 행들만 남김
    • 원본 객체 변경 place=True
    • dropduplicates([]) : 열 기준으로 판단
df.drop_duplicates()
df.drop_duplicates(['c2','c3'])



1.3. 3) 데이터 표준화 (***)

  • 참고측정단위가 서로 다른 자료를 비교할 때는 더욱 요긴함
  • 변동계수의 값이 클수록 데이터의 상대적인 값의 차이가 크다는 것을 의미
  • 변동계수(cv) : 변동계수는 표준편차를 산술평균으로 나눈 것

1.3.1. 3-1 단위 환산

  • 같은 데이터셋 안에서 서로 다른 측정 단위 >> 같은 측정 단위
# mpg(mile per gallon) >> kpl (km per liter)

mpg_to_kpl = 1.60934 / 3.78541

df['kpl'] = df['mpg'] * mpg_to_kpl

df['kpl'] = round(df['kpl'],2)  # df['kpl'].round(2) 소수점 둘째자리까지



1.3.2. 3-2) 자료형 변환

  • 고유값 확인
    • df.unique()
  • 자료형 확인
    • df.dtypes
  • ype()
df['horsepower'].replace('?', np.nan, inplace=True) # ? >> nan 변환
df.dropna(subset=['horsepower'], axis=0, inplace=True) # 누락 데이터 있는 행 삭제
df['horsepower'] = df['horsepower'].astype('float') # 문자열(object) >>  실수형(float)
  • replace()
# 정수형 데이터 >> 문자형 데이터 
df['origin'].replace({1:'USA', 2:'EU',3:'KOREA'}, inplace=True)

# dtype('O')
# 문자열 >> 범주형 
df['origin'] = df['origin'].astype('category')

# 범주형 >> 문자열 반환
df['origin'] = df['origin'].astype('str')



1.4. 4) 범주형(카테고리) 데이터 처리

1.4.1. 4-1 구간 분할

  • 연속 데이터를 그대로 사용하기 보다는 일정한 구간(bin)으로 나눠서 분석하는 것이 효율 적
  • (binning) : 연속 변수 >> 일정한 구간 >> 범주형 이산 변수로 변환

 

  • hisgram(df,bs=)
    • bs : 나누려는 구간(bin) 개수
    • 각 구간에 속하는 값의 개수 (count), 경계값 리스트 (bin_dividers)
# np.histogram 함수로 3개의  bin으로 나누는 경계 값의 리스트 구하기
count, bin_dividers  = np.histogram(df['horsepower'], bins=3)

 

  • cut()
    • bs : 경계값의 리스트(bin_dividers)
    • cludelowest=True : 각 구간의 낮은 경계값 포함
bin_names = ['저출력', '보통 출력', '고출력']
df['hp_bin'] = pd.cut(x=df['horsepower'],
               bins = bin_dividers,
               labels = bin_names, 
               include_lowest=True)



1.4.2. 4-2 더미 변수

  • 카테고리를 나타내는 범주형 데이터를 회귀분석 등 머신러닝 알고리즘에 바로 사용할 수 없음 >> 컴퓨터가 인식 가능한 입력값으로 변환
  • (dummpyvariab) : 숫자 0 또는 1로 표현
  • 0, 1은 어떤 특성(feature)이 있는지 없는지 여부만 표시
  • 특성이 존재하면 1, 존재하지 않으면 0

 

  • (ohotr) : 0과 1로만 구성
  • (o-hot-encodg) : 범주형 데이터를 원핫벡터로 변환
  • ==get_dummies()==
    • 범주형 데이터의 모든 고유값 >> 새로운 더미 변수로 변환
# 더미 변수
hp_dummy = pd.get_dummies(df['hp_bin'])
  • sklearn 라이브러리 이용해서 원핫인코딩 처리
    • 1차원 벡터 >> 2차원 행렬 >> 희소행렬
    • (sparsematrix)
      • (행, 열) 좌표와 값 형태로 정리
      • (0,1) : 0행의 1열 위치
      • 데이터 값: 숫자 1,0
# one-hot encoding
from sklearn import preprocessing 

# 전처리를 위한 encoder 객체 만들기
le = preprocessing.LabelEncoder()  # label encoder
oh = preprocessing.OneHotEncoder()  # one hot encoder

# label encoder로 문자열 범주 >> 숫자형 범주로 변환(0,1,2)
onehot_le = le.fit_transform(df['hp_bin'])

# 2 차원 행렬 구조 변환
onehot_le_matrix = onehot_le.reshape(len(onehot_le),1)

# 희소행렬 
oh.fit_transform(onehot_le_matrix)



1.5. 5) 정규화

  • 정규화(normalization)
    • 각 열(변수)에 속하는 데이터값을 동일한 크기 기준으로 나눈 비율로 나타내는 것
    • 데이터 범위 01 또는 -11
  • min-max scailing (범주 : 0~1)
# horsepower 열의 통계 요약정보 >> 최대값(max), 최소값(min) 확인 
df.horsepower.describe()
# min       46,  max      230

# (x - x.min) / (x.max - x.min)

min_x = df['horsepower'] - df['horsepower'].min()
min_max = df['horsepower'].max() - df['horsepower'].min()

df.horsepower_minmax =  min_x / min_max



1.6. 6) 시계열 데이터

1.6.1. 6-1 다른 자료형을 시계열 객체로 변환

  • 문자열을 Timestamp로 변환 : ==to_datetime==
    • datetime()
    • 문자열 등 다른 자료형 >> 판다스 Timestamp (datetime64)
df['new_Date'] = pd.to_datetime(df['Date']) # df에 새로운 열로 추가

 

  • Timestamp를 Period로 변환 : ==to_period==
    • period()
    • Timestamp >> Period(일정한 기간을 나타내는 함수)
    • period(eq=)
    • freq 옵션 : 기준이 되는 시간

freq 옵션설명

D day (1일)
W week(1주)
M month end(월말)
Q quarter end(분기말)
A year end(연말)
B business day(휴일 제외)
pr_day = ts_dates.to_period(freq='D')



1.6.2. 6-2 시계열 데이터 만들기

  • Timestamp 배열 : ==date_range==
    • dateran()
    • 여러 개의 날짜(Timestamp)가 들어 있는 배열 형태
pd.date_range('2019-01-01',        # 날짜 범위 시작 지정
              end = None,          # 날짜 범위 끝 지정 (default : None)
              periods=6,           # 생성할 Timestamp 개수
              freq='MS',           # 시간 간격(MS : 월의 시작일)
              tz = 'Asia/Seoul')   # 시간대(timezone)
  • Period 배열 : ==period_range==
    • periodran()
    • 여러 개의 기간(Period)가 들어 있는 시계열 데이터를 만듦
pd.period_range(start = '2019-01-01',   # 날짜 범위 시작
              end = None,               # 날짜 범위 끝 (default : None)
              periods=3,                # 생설할 Period 개수
              freq='M')                 # 기간의 길이(frequency) 'M':월(Month)



1.6.3. 6-3 시계열 데이터 활용

  • 날짜 데이터 분리
    • 연-월-일 날짜 데이터에서 일부를 추출할 수 있다.
    • 연-월-일 정보를 연, 월, 일 각각으로 구분
    • dt속성 이용
df['year'] = df['new_date'].dt.year
df['month'] = df['new_date'].dt.month
df['day'] = df['new_date'].dt.day
# TimestampPeriod로 변환하여 연--일로 변경하기
df['date_yr'] = df['new_date'].dt.to_period(freq='A')
df['date_m'] = df['new_date'].dt.to_period(freq='M')
# 데이터프레임의 행 인덱스로 지정
df.set_index('date_m', inplace=True)

 

  • 날짜 인덱스 활용
    • Timestamp로 구성된 열을 행 인덱스로 지정하면 DatetimeIndex라는 고유 속성으로 변환
    • Period로 구성된 열을 행 인덱스로 지정하면 DatetimeIndex라는 고유 속성으로 변환
    • datetime() 메소드 이용
    • 행 인덱스로 지정 : setdex() 메소드
# loc를 이용해 선택적으로 인덱싱
df_y = df['2018']
df_ym = df.loc['2018-07']
df_ymd = df.loc['2018-07-02']
# 날짜 범위로 슬라이싱 추출
df['2018-06-20':'2018-06-25']  # 날짜 범위
df_ym_cols = df.loc['2018-07', 'Start':'High'] # 열 범위 슬라이싱

 

  • 날짜 인덱스 활용 - 두 날짜 사이의 시간 간격
    • Timestamp 객체로 표시된 두 날짜 사이의 시간 간격을 구할 수 있다.
    • 날짜 차이 계산 : **today - df.index**
today = pd.to_datetime('2018-12-25')  # 기준일 생성
df['time_delta'] = today - df.index   # 날짜 차이 계산
df.set_index(df['time_delta'], inplace=True)
df['180 days':'189 days']             # 180~189일 사이의 값들만 선택




2. 6. 데이터프레임의 다양한 응용

2.1. 1) 함수 매핑

2.1.1. 1-1 개별 원소에 함수 매핑

  • 시리즈 원소에 함수 매핑 : ==Series객체.apply(매핑 함수)==
    • apply()
    • **시리즈 모든 원소**
    • 시리즈 객체에 apply()메소드를 적용하면 인자로 전달하는 매핑 함수에 시리즈 모든 원소를 하나씩 입력하고 함수의 리턴값을 돌려받는다.
    • 시리즈 원소의 개수만큼 리턴값을 받아서 같은 크기의 시리즈 객체로 반환
def add_10(n): # 10을 더해주는 함수
    return n+10

df['age'].apply(lambda x : add_10(x))

 

  • 데이터프레임의 원소에 함수 매핑 : ==DataFrame 객체.applymap(매핑 함수)==
    • applymap()
    • **데이터 프레임의 개별 원소**
    • 매핑 함수에 데이터프레임의 각 원소를 하나씩 넣어서 리턴값으로 돌려받는다.
    • 원소의 원래 위치에 매핑 함수의 리턴값을 입력하여 동일한 형태의 데이터프레임이 만들어진다.
def add_10(n): # 10을 더해주는 함수
    return n+10

df.applymap(add_10)



2.1.2. 1-2 시리즈 객체에 함수 매핑

  • 데이터프레임의 각 열에 함수 매핑 : ==DataFrame 객체.apply(매핑 함수, axis=0)==
    • apply(aξs=0)
    • **데이터프레임의 각 열**
    • 모든 열을 하나씩 분리하여 매핑 함수의 인자로 각 열(시리즈)이 전달됨
    • 시리즈를 입력받고 시리즈를 반환하는 함수를 매핑하면, 데이터프레임을 반환
    • isνll() 메소드 : 시리즈 객체에서 누락 데이터를 찾고 그 결과를 불린 시리즈 형태로 반환
def missing_value(series):
    return series.isnull()  # boolean series 반환

df.apply(missing_value, axis=0)

 

  • 데이터프레임의 각 열에 함수 매핑 : ==DataFrame 객체.apply(매핑 함수, axis=0)==
    • 시리즈를 입력받아서 하나의 값을 반환하는 함수를 매핑하면, 시리즈를 반환
def min_max(x):
    return x.max() - x.min()

df.apply(min_max)

 

  • 데이터프레임의 각 행에 함수 매핑 : ==DataFrame 객체.apply(매핑 함수, axis=1)==
    • apply(aξs=1)
    • **데이터프레임의 각 행**
    • 데이터프레임의 행 인덱스가 매핑 결과르 반환되는 시리즈의 인덱스가 됨
    • 시리즈의 인덱스에 매칭되는 데이터 값에는 각 행의 데이터를 함수에 적용한 리턴값
def add_tow_obj(a,b):  # 받은 인자 2개를 더해주는 함수
    return a+b

df['add'] = df.apply(lambda x : add_tow_obj(x['age'], x['ten']), axis=1)



2.1.3. 1-3 데이터프레임 객체에 함수 매핑

  • 데이터프레임 객체에 함수 매핑 : ==DataFrame 객체.pipe(매핑 함수)==
    • πpe()
    • **데이터프레임 객체**
    • 데이터프레임을 반환하는 경우, 시리즈를 반환하는 경우, 개별 값을 반환하는 경우
def missing_value(series):
    return series.isnull()  # boolean series 반환

# 각 열의 NaN 찾기 - 데이터프레임을 전달하면 데이터프레임 변환
def missing_value(x):
    return x.isnull()

# 각 열의 NaN 개수 반환 - 데이터프레임을 전달하면 시리즈 변환
def missing_count(x):
    return missing_value(x).sum()  # missing_value(x) >> 시리즈

# 데이터프레임의 총 NaN 개수 - 데이터프레임을 전달하면 값 반환
def total_number_missing(x):
    return missing_count(x).sum()
# pipe() : df 에 적용됨

df.pipe(missing_value)
# >> 데이터프레임

df.pipe(missing_count)
# >> age     177
#    fare      0
#    dtype: int64

df.pipe(total_number_missing)
# 177




2.2. 2) 열 재구성

2.2.1. 2-1 열 순서 변경

  • 데이터프레임의 열 순서 변경 : ==DataFrame 객체[재구성한 열 이름의 리스트]==
    • 마지막 범위 값 포함
df = titanic.loc[0:4, 'survived':'age']

 

  • list() : 데이터프레임 열 >> 리스트
df.columns
## index

df.columns.values
## 값들 >> array

list(df.columns.values)
# 리스트

 

  • sorted(columns) : 열 이름 >> 알파벳 순으로 정렬
columns_sorted = sorted(columns)  # 열 이름을 알파벳 순으로 정렬
df_sorted = df[columns_sorted]

 

  • reversed(columns) : 기존 순서의 정반대 역순으로 정렬
columns_reversed = list(reversed(columns))  # 정렬된 열 이름의 리스트 이용
df_reversed = df[columns_reversed]

 

  • columnscusmed : 임의의 순서로 열 이름 재배치
    • 임의의 순서로 열 이름을 재배치한 상태로 데이터프레임 df에서 각 열을 순서에 맞춰서 선택
columns_customed = ['pclass', 'sex', 'age', 'survived']
df_customed = df[columns_customed]



2.2.2. 2-2 열 분리

  • ype() 메소드 : 자료형 변경
    • '연월일' 열의 시간형 데이터를 문자열로 변경
    • ==df.str.split()==
    • 문자열을 split() 메소드를 분리
df['연월일'] = df['연월일'].astype('str')  # 문자열 메소드 사용을 위해 자료형 변경
df['연월일'].str.split('-')  # 문자열을 split() 메소드로 분리

 

  • 시리즈의 문자열 리스트 인덱싱 : ==Series 객체.str.get(인덱스)==
    • str.t()
    • **문자열 리스트의 원소 선택**
df['연'] = dates.str.get(0)
df['월'] = dates.str.get(1)
df['일'] = dates.str.get(2)



2.3. 3) 필터링

2.3.1. 3-1 불린 인덱싱

  • 참/거짓
  • 시리즈 객체에 어떤 조건식을 적용하면 각 원소에 대해 참/거짓을 판별하여 불린(참/거짓) 값으로 구성된 시리즈를 반환

 

  • 데이터프레임 불린 인덱싱 : ==DataFrame 객체[불린 시리즈]==
# 나이가 10대(10~19세)만 추출하시오.
condition = (titanic.age >= 10) & (titanic.age < 20)

# 1번째 방법
titanic[condition]
# 2번째 방법
titanic.loc[condition, :]
# 나이가 10세 미만(0~9세) 또는 60세 이상인 승객의 age, sex, alone 열만 선택

condition = (titanic.age < 10) | (titanic.age >= 60)
titanic.loc[condition, ['age','sex','alone']]



2.3.2. 3-2 isin() 메소드 활용

  • isin() 메소드를 활용한 필터링 : ==DataFrame의 열 객체.isin(추출 값의 리스트)==
    • isin() : 특정 값을 가진 행들을 따로 추출 가능
    • **T/F 반환**
# 함께 탑승한 형제 또는 배우자 수가 3, 4, 5 인 승객만 따로 추출하시오
mask_3 = titanic['sibsp'] == 3
mask_4 = titanic['sibsp'] == 4
mask_5 = titanic['sibsp'] == 5
condition = (mask_3) | (mask_4) | (mask_5)
titanic[condition]
condition = titanic['sibsp'].isin([3,4,5])
titanic[condition]



2.4. 4) 데이터프레임 합치기

2.4.1. 4-1 데이터프레임 연결

  • 데이터프레임 연결 : ==Pandas.concat(데이터프레임의 리스트)==
    • concat()
    • 이어 붙이듯 연결
    • 데이터프레임을 원소로 갖는 리스트를 전달하면 여러 개의 데이터프레임을 서로 연결
    • default : **axis=0** (행 방향으로 연결)
      • aξs=1 : 열 방향으로 연결
    • default : **join = 'outer'** (합집합)
      • jo=r : 교집합
    • ignoredex=True : 기존 행 인덱스를 무시하고 새로운 행 인덱스 설정

pd.concat([df1,df2], axis=1, join='inner')

abcabcd

2 a2 b2 c2 a2 b2 c2 d2
3 a3 b3 c3 a3 b3 c3 d3



2.4.2. 4-2 데이터프레임 병합

  • 데이터프레임 병합 : ==Pandas.merge( df_left, df_right, how='inner', on=None)==
    • mer()
    • 어떤 기준에 의해 두 데이터프레임 병합
    • SQL join 명령과 비슷
    • 기준이 되는 열이나 인덱스를 키(key) - 양쪽 데이터프레임에 모두 존재해야 함
    • default : **on=None** (공통으로 속하는 모든 열을 기준(key)으로 병합)
      • on= : 공통 열 중 'id' 열을 키로 병합
    • default : **how='inner'** (교집합일 경우에만 추출)
      • how=outer : 기준 데이터가 데이터프레임 중 어느 한쪽에만 속하더라도 포함
      • how=ft : 왼쪽 데이터프레임의 키 열에 속하는 데이터 값을 기준으로 병합
        • fton, righton 옵션으로 좌우 데이터프레임에 각각 다르게 키를 지정 가능
      • 어느 한 쪽이라도 데이터가 없는 열에는 NaN값
pd.merge(df1, df2, how='left', left_on='stock_name', right_on = 'name')



2.4.3. 4-3 데이터프레임 결합

  • 행 인덱스 기준으로 결합 : ==DataFrame1.join(DataFrame2, how='left')==
    • 두 데이터프레임의 행 인덱스를 기준으로 결합
    • on=keys옵션을 설정하면 행 인덱스 대신 다른 열을 기준으로 결합
    • dexcol옵션을 적용하여 행 인덱스 설정 가능
    • default : **how='left'** (왼쪽 df의 행 인덱스를 기준으로 결합)
      • how=r : 두 데이터프레임에 공통으로 존재하는 행 인덱스 기준으로 추출
df1.join(df2, how='inner')



2.5. 5) 그룹 연산

  • 1단계) 분할(split) : 데이터를 특정 조건에 의해 분할
  • 2단계) 적용(apply) : 데이터 집계, 변환, 필터링하는데 필요한 메소드 적용
  • 3단계) 결합(combine) : 2단계의 처리 결과를 하나로 결합

2.5.1. 5-1 그룹 객체 만들기(분할 단계)

  • 그룹 연산(분할) : ==DataFrame 객체.groupby(기준이 되는 열)==
    • 데이터프레임의 특정 열을 기준으로 데이터프레임을 분할하여 그룹 객체를 반환
    • tgroup() 메소드를 적용하면 특정 그룹만을 선택할 수 있다.
df = titanic.loc[:,['age','sex','class','fare','survived']]
grouped = df.groupby(['class'])
grouped.get_group('Third')  # 특정 그룹만 선택
grouped.mean() # mean() : 평균
grouped.std()  # std() : 표준편차

 

  • 그룹 연산(분할) : ==DataFrame 객체.groupby(기준이 되는 열의 리스트)==
    • 여러 개의 기준 값을 사용
    • 반환되는 그룹 객체의 인덱스는 다중 구조를 갖음
grouped_two = df.groupby(['class','sex'])
grouped_two.get_group(('Third','female'))  # 특정 그룹만 선택
grouped_two.mean() # >> 멀티 인덱스



2.5.2. 5-2 그룹 연산 메소드(적용 - 결합 단계)

  • 표준편차 데이터 집계(내장 함수) : ==group 객체.std()==
    • 데이터 집계 (aggreagation)
    • mean(), max(), min(), sum(), count(), size(), var(), std(), describe(), info(), first(), last()

 

  • agg() 메소드 데이터 집계 : ==group 객체.agg(매핑 함수)==
def min_max(x):
    return x.max() - x.min()

grouped.agg(min_max)

 

  • 모든 열에 여러 함수 매핑 : ==group 객체.agg([함수1, 함수2, 함수3, ... ])==
grouped.agg(['min','max'])
# sex는 범주형 데이터라 min_max 안됨

 

  • 각 열마다 다른 함수를 매핑 : ==group 객체.agg({'열1' : 함수1, '열2' : 함수2, ...})==
grouped.agg({'fare':['min','max'],
            'age':'mean'})

 

  • 데이터 변환 연산 : ==group 객체.transform(매핑 함수)==
    • tranorm()
    • 그룹 별로 구분하여 각 원소에 함수를 적용하지만 그룹별 집계 대신 각 원소의 본래 행 인덱스와 열 이름을 기준으로 연산 결과를 반환
    • 그룹 연산의 결과를 원본 데이터프레임과 같은 형태로 변형하여 정리
# 그룹 객체의 age 열을 iteration으로 z-score를 계산하여 출력
for key, group in grouped.age:
    group_zscore = (group - grouped.age.mean().loc[key]) / grouped.age.std().loc[key]

 

# z-score 계산하는 사용자 함수 정의
def z_score(x):
    return (x-x.mean()) / x.std()

age_zscore = grouped.age.transform(z_score)

z-score 계산하는 사용자 함수 정의, tranorm() 메소드의 인자로 전달

 

  • 그룹 객체 필터링 : ==group 객체.filter(조건식 함수)==
    • fi<er()
    • 조건이 참인 그룹의 데이터만 추출
# 데이터 개수가 200개 이상인 것만 추출
grouped_filter = grouped.filter(lambda x : len(x) >= 200)

 

  • 범용 메소드 : ==group 객체.apply(매핑 함수)==
    • apply() (메소드)
    • 판다스 객체의 개별 원소를 특정 함수에 일대일로 매핑
    • 사용자가 원하는 대부분의 연산을 그룹 객체에도 적용할 수 있음
    • default : **axis=0**
age_grouped = grouped.apply(lambda x: x.describe())

 

# z-score 계산을 apply()로 해볼까요?

def z_score(x):
    return (x-x.mean()) / x.std()

age_zscore = grouped.age.apply(z_score)  # default : axis=0

 

# 필터링 : age 열의 데이터 평균이 30보다 작은 그룹만을 필터링하여 출력

age_filter = grouped.apply(lambda x: x.age.mean() < 30)

for x in age_filter.index:
    if age_filter[x] == True:
        print(grouped.get_group(x))
        print('\n')



2.6. 6) 멀티 인덱스

  • loc 인덱서
  • xs 인덱서
# class 열, sex 열을 기준으로 분할
grouped = df.grouped(['class','sex'])

# 그룹 객체에 연산 메소드 적용
gdf = grouped.mean()

# class : First >> sex : female
gdf.loc[('First','female')]

# sex값이 male인 행 선택, 출력
gdf.xs('male', level='sex')




2.7. 7) 피벗

  • πvottab()
  • 엑셀에서 사용하는 피벗테이블과 비슷한 기능
# 행, 열, 값, 집계함수 (default: 평균)

df3 = pd.pivot_table(df,                # 피벗할 데이터프레임
               index=['class', 'sex'],  # 행 위치에 들어갈 열
               columns='survived',      # 열 위치에 들어갈 열
               values= ['age','fare'],  # 데이터로 사용할 열
               aggfunc=['mean', 'max']) # 데이터 집계 함수

# Ipython Console 디스플레이 옵션 설정
pd.set_option('display.max_columns', 10)  # 출력할 열의 최대 개수

 

  • xs인덱서 사용
    • default : **행 인덱스**
    • default : **axis=0**
      • 열 선택 : aξs=1
df3.xs('male', level='sex')
# sex 레벨에서 남성 승객 데이터만 추출 

df3.xs(('Second','male'), level=[0, 'sex'])
# second, male인 행 선택 
df3.xs(('max', 'fare', 0),
      level=[0,1,2], axis=1)
# max, fare, survived=0 인 데이터 선택 

3. 5. 데이터 사전 처리

3.1. 1) 누락 데이터 처리

  • 누락 데이터 확인
    • fo() : 데이터프레임 요약 정보 - 유효한 값의 개수를 보여줌
    • valuecounts(dropna=False) : 누락 데이터 개수 확인 ( default : **dropna = True**)
    • ==isnull()== : **누락 데이터**면 True를 반환, 유요한 데이터가 존재하면 False를 반환
      • df.isνll().(aξs=0)
    • ==notnull()== : **유효한 데이터**가 존재하면 True를 반환하고, 누락 데이터면 False를 반환

 

  • 누락 데이터 제거
    • 열을 삭제하면 분석 대상이 갖는 특성(변수)를 제거
    • 행을 삭제하면 분석 대상의 관측값(레코드) 제거
    • ==dropna(thresh=500)==
# for 반복문 각 열의 NaN 개수 계산하기(묘미***)
null_df = df.isnull()

for col in null_df.columns: 
    null_count = null_df[col].value_counts() # 각 열의 NaN 개수 파악 

    try: 
        print(col, ':', null_count[True])  # NaN 값이 있으면 개수 출력
    except: 
        print(col, ':', 0)  # NaN 값이 없으면 0개 출력
# NaN 값이 500개 이상(threshold)인 열 모두 삭제

df_thresh = df.dropna(axis=1, thresh=500)
# deck 의 NaN 688 개만 적용됨 
# age 열에 나이 데이터가 없는 모든 행 삭제 
df_age = df.dropna(subset=['age'], how='any', axis=0)

 

  • 누락 데이터 치환
    • ==fillna(inplace=True)==
    • fillna()
      • place=True 옵션을 추가해야 원본 객체 변경
      • 주의해서 사용!
# age의 열의 NaN 값을 다른 나이 데이터 평균으로 변경하기 
mean_age = df['age'].mean(axis=0)   # age 열의 평균 계산 (NaN 값 제외)
df['age'].fillna(mean_age, inplace=True)

 

    • 가장 많이 출현한 값
# most_freq (비정형 데이터 : 최대빈도)
most_freq = df['embark_town'].value_counts(dropna=True).idxmax()
df_embark_town_null['embark_town'].fillna(most_freq)

 

  • fillna(method=ffill)
    • NaN이 있는 행의 직전 행에 있는 값으로 바꿔줌
    • method=bfill : 다음 행에 있는 값
df['embark_town'].fillna(method='ffill', inplace=True)
df['embark_town'][825:830]



3.2. 2) 중복 데이터 처리

  • 중복 데이터 확인 : ==duplicated()==
    • duplicated()
    • 행의 레코드가 중복되는지 여부
    • 중복되는 행이면 True, 처음 나오는 행은 False
df_dup = df.duplicated()

 

  • 중복 데이터 제거 : ==drop_duplicates()==
    • 중복되는 행을 제거하고 고유한 관측값을 가진 행들만 남김
    • 원본 객체 변경 place=True
    • dropduplicates([]) : 열 기준으로 판단
df.drop_duplicates()
df.drop_duplicates(['c2','c3'])



3.3. 3) 데이터 표준화 (***)

  • 참고측정단위가 서로 다른 자료를 비교할 때는 더욱 요긴함
  • 변동계수의 값이 클수록 데이터의 상대적인 값의 차이가 크다는 것을 의미
  • 변동계수(cv) : 변동계수는 표준편차를 산술평균으로 나눈 것

3.3.1. 3-1 단위 환산

  • 같은 데이터셋 안에서 서로 다른 측정 단위 >> 같은 측정 단위
# mpg(mile per gallon) >> kpl (km per liter)

mpg_to_kpl = 1.60934 / 3.78541

df['kpl'] = df['mpg'] * mpg_to_kpl

df['kpl'] = round(df['kpl'],2)  # df['kpl'].round(2) 소수점 둘째자리까지



3.3.2. 3-2) 자료형 변환

  • 고유값 확인
    • df.unique()
  • 자료형 확인
    • df.dtypes
  • ype()
df['horsepower'].replace('?', np.nan, inplace=True) # ? >> nan 변환
df.dropna(subset=['horsepower'], axis=0, inplace=True) # 누락 데이터 있는 행 삭제
df['horsepower'] = df['horsepower'].astype('float') # 문자열(object) >>  실수형(float)
  • replace()
# 정수형 데이터 >> 문자형 데이터 
df['origin'].replace({1:'USA', 2:'EU',3:'KOREA'}, inplace=True)

# dtype('O')
# 문자열 >> 범주형 
df['origin'] = df['origin'].astype('category')

# 범주형 >> 문자열 반환
df['origin'] = df['origin'].astype('str')



3.4. 4) 범주형(카테고리) 데이터 처리

3.4.1. 4-1 구간 분할

  • 연속 데이터를 그대로 사용하기 보다는 일정한 구간(bin)으로 나눠서 분석하는 것이 효율 적
  • (binning) : 연속 변수 >> 일정한 구간 >> 범주형 이산 변수로 변환

 

  • hisgram(df,bs=)
    • bs : 나누려는 구간(bin) 개수
    • 각 구간에 속하는 값의 개수 (count), 경계값 리스트 (bin_dividers)
# np.histogram 함수로 3개의  bin으로 나누는 경계 값의 리스트 구하기
count, bin_dividers  = np.histogram(df['horsepower'], bins=3)

 

  • cut()
    • bs : 경계값의 리스트(bin_dividers)
    • cludelowest=True : 각 구간의 낮은 경계값 포함
bin_names = ['저출력', '보통 출력', '고출력']
df['hp_bin'] = pd.cut(x=df['horsepower'],
               bins = bin_dividers,
               labels = bin_names, 
               include_lowest=True)



3.4.2. 4-2 더미 변수

  • 카테고리를 나타내는 범주형 데이터를 회귀분석 등 머신러닝 알고리즘에 바로 사용할 수 없음 >> 컴퓨터가 인식 가능한 입력값으로 변환
  • (dummpyvariab) : 숫자 0 또는 1로 표현
  • 0, 1은 어떤 특성(feature)이 있는지 없는지 여부만 표시
  • 특성이 존재하면 1, 존재하지 않으면 0

 

  • (ohotr) : 0과 1로만 구성
  • (o-hot-encodg) : 범주형 데이터를 원핫벡터로 변환
  • ==get_dummies()==
    • 범주형 데이터의 모든 고유값 >> 새로운 더미 변수로 변환
# 더미 변수
hp_dummy = pd.get_dummies(df['hp_bin'])
  • sklearn 라이브러리 이용해서 원핫인코딩 처리
    • 1차원 벡터 >> 2차원 행렬 >> 희소행렬
    • (sparsematrix)
      • (행, 열) 좌표와 값 형태로 정리
      • (0,1) : 0행의 1열 위치
      • 데이터 값: 숫자 1,0
# one-hot encoding
from sklearn import preprocessing 

# 전처리를 위한 encoder 객체 만들기
le = preprocessing.LabelEncoder()  # label encoder
oh = preprocessing.OneHotEncoder()  # one hot encoder

# label encoder로 문자열 범주 >> 숫자형 범주로 변환(0,1,2)
onehot_le = le.fit_transform(df['hp_bin'])

# 2 차원 행렬 구조 변환
onehot_le_matrix = onehot_le.reshape(len(onehot_le),1)

# 희소행렬 
oh.fit_transform(onehot_le_matrix)



3.5. 5) 정규화

  • 정규화(normalization)
    • 각 열(변수)에 속하는 데이터값을 동일한 크기 기준으로 나눈 비율로 나타내는 것
    • 데이터 범위 01 또는 -11
  • min-max scailing (범주 : 0~1)
# horsepower 열의 통계 요약정보 >> 최대값(max), 최소값(min) 확인 
df.horsepower.describe()
# min       46,  max      230

# (x - x.min) / (x.max - x.min)

min_x = df['horsepower'] - df['horsepower'].min()
min_max = df['horsepower'].max() - df['horsepower'].min()

df.horsepower_minmax =  min_x / min_max



3.6. 6) 시계열 데이터

3.6.1. 6-1 다른 자료형을 시계열 객체로 변환

  • 문자열을 Timestamp로 변환 : ==to_datetime==
    • datetime()
    • 문자열 등 다른 자료형 >> 판다스 Timestamp (datetime64)
df['new_Date'] = pd.to_datetime(df['Date']) # df에 새로운 열로 추가

 

  • Timestamp를 Period로 변환 : ==to_period==
    • period()
    • Timestamp >> Period(일정한 기간을 나타내는 함수)
    • period(eq=)
    • freq 옵션 : 기준이 되는 시간

freq 옵션설명

D day (1일)
W week(1주)
M month end(월말)
Q quarter end(분기말)
A year end(연말)
B business day(휴일 제외)
pr_day = ts_dates.to_period(freq='D')



3.6.2. 6-2 시계열 데이터 만들기

  • Timestamp 배열 : ==date_range==
    • dateran()
    • 여러 개의 날짜(Timestamp)가 들어 있는 배열 형태
pd.date_range('2019-01-01',        # 날짜 범위 시작 지정
              end = None,          # 날짜 범위 끝 지정 (default : None)
              periods=6,           # 생성할 Timestamp 개수
              freq='MS',           # 시간 간격(MS : 월의 시작일)
              tz = 'Asia/Seoul')   # 시간대(timezone)
  • Period 배열 : ==period_range==
    • periodran()
    • 여러 개의 기간(Period)가 들어 있는 시계열 데이터를 만듦
pd.period_range(start = '2019-01-01',   # 날짜 범위 시작
              end = None,               # 날짜 범위 끝 (default : None)
              periods=3,                # 생설할 Period 개수
              freq='M')                 # 기간의 길이(frequency) 'M':월(Month)



3.6.3. 6-3 시계열 데이터 활용

  • 날짜 데이터 분리
    • 연-월-일 날짜 데이터에서 일부를 추출할 수 있다.
    • 연-월-일 정보를 연, 월, 일 각각으로 구분
    • dt속성 이용
df['year'] = df['new_date'].dt.year
df['month'] = df['new_date'].dt.month
df['day'] = df['new_date'].dt.day
# TimestampPeriod로 변환하여 연--일로 변경하기
df['date_yr'] = df['new_date'].dt.to_period(freq='A')
df['date_m'] = df['new_date'].dt.to_period(freq='M')
# 데이터프레임의 행 인덱스로 지정
df.set_index('date_m', inplace=True)

 

  • 날짜 인덱스 활용
    • Timestamp로 구성된 열을 행 인덱스로 지정하면 DatetimeIndex라는 고유 속성으로 변환
    • Period로 구성된 열을 행 인덱스로 지정하면 DatetimeIndex라는 고유 속성으로 변환
    • datetime() 메소드 이용
    • 행 인덱스로 지정 : setdex() 메소드
# loc를 이용해 선택적으로 인덱싱
df_y = df['2018']
df_ym = df.loc['2018-07']
df_ymd = df.loc['2018-07-02']
# 날짜 범위로 슬라이싱 추출
df['2018-06-20':'2018-06-25']  # 날짜 범위
df_ym_cols = df.loc['2018-07', 'Start':'High'] # 열 범위 슬라이싱

 

  • 날짜 인덱스 활용 - 두 날짜 사이의 시간 간격
    • Timestamp 객체로 표시된 두 날짜 사이의 시간 간격을 구할 수 있다.
    • 날짜 차이 계산 : **today - df.index**
today = pd.to_datetime('2018-12-25')  # 기준일 생성
df['time_delta'] = today - df.index   # 날짜 차이 계산
df.set_index(df['time_delta'], inplace=True)
df['180 days':'189 days']             # 180~189일 사이의 값들만 선택




4. 6. 데이터프레임의 다양한 응용

4.1. 1) 함수 매핑

4.1.1. 1-1 개별 원소에 함수 매핑

  • 시리즈 원소에 함수 매핑 : ==Series객체.apply(매핑 함수)==
    • apply()
    • **시리즈 모든 원소**
    • 시리즈 객체에 apply()메소드를 적용하면 인자로 전달하는 매핑 함수에 시리즈 모든 원소를 하나씩 입력하고 함수의 리턴값을 돌려받는다.
    • 시리즈 원소의 개수만큼 리턴값을 받아서 같은 크기의 시리즈 객체로 반환
def add_10(n): # 10을 더해주는 함수
    return n+10

df['age'].apply(lambda x : add_10(x))

 

  • 데이터프레임의 원소에 함수 매핑 : ==DataFrame 객체.applymap(매핑 함수)==
    • applymap()
    • **데이터 프레임의 개별 원소**
    • 매핑 함수에 데이터프레임의 각 원소를 하나씩 넣어서 리턴값으로 돌려받는다.
    • 원소의 원래 위치에 매핑 함수의 리턴값을 입력하여 동일한 형태의 데이터프레임이 만들어진다.
def add_10(n): # 10을 더해주는 함수
    return n+10

df.applymap(add_10)



4.1.2. 1-2 시리즈 객체에 함수 매핑

  • 데이터프레임의 각 열에 함수 매핑 : ==DataFrame 객체.apply(매핑 함수, axis=0)==
    • apply(aξs=0)
    • **데이터프레임의 각 열**
    • 모든 열을 하나씩 분리하여 매핑 함수의 인자로 각 열(시리즈)이 전달됨
    • 시리즈를 입력받고 시리즈를 반환하는 함수를 매핑하면, 데이터프레임을 반환
    • isνll() 메소드 : 시리즈 객체에서 누락 데이터를 찾고 그 결과를 불린 시리즈 형태로 반환
def missing_value(series):
    return series.isnull()  # boolean series 반환

df.apply(missing_value, axis=0)

 

  • 데이터프레임의 각 열에 함수 매핑 : ==DataFrame 객체.apply(매핑 함수, axis=0)==
    • 시리즈를 입력받아서 하나의 값을 반환하는 함수를 매핑하면, 시리즈를 반환
def min_max(x):
    return x.max() - x.min()

df.apply(min_max)

 

  • 데이터프레임의 각 행에 함수 매핑 : ==DataFrame 객체.apply(매핑 함수, axis=1)==
    • apply(aξs=1)
    • **데이터프레임의 각 행**
    • 데이터프레임의 행 인덱스가 매핑 결과르 반환되는 시리즈의 인덱스가 됨
    • 시리즈의 인덱스에 매칭되는 데이터 값에는 각 행의 데이터를 함수에 적용한 리턴값
def add_tow_obj(a,b):  # 받은 인자 2개를 더해주는 함수
    return a+b

df['add'] = df.apply(lambda x : add_tow_obj(x['age'], x['ten']), axis=1)



4.1.3. 1-3 데이터프레임 객체에 함수 매핑

  • 데이터프레임 객체에 함수 매핑 : ==DataFrame 객체.pipe(매핑 함수)==
    • πpe()
    • **데이터프레임 객체**
    • 데이터프레임을 반환하는 경우, 시리즈를 반환하는 경우, 개별 값을 반환하는 경우
def missing_value(series):
    return series.isnull()  # boolean series 반환

# 각 열의 NaN 찾기 - 데이터프레임을 전달하면 데이터프레임 변환
def missing_value(x):
    return x.isnull()

# 각 열의 NaN 개수 반환 - 데이터프레임을 전달하면 시리즈 변환
def missing_count(x):
    return missing_value(x).sum()  # missing_value(x) >> 시리즈

# 데이터프레임의 총 NaN 개수 - 데이터프레임을 전달하면 값 반환
def total_number_missing(x):
    return missing_count(x).sum()
# pipe() : df 에 적용됨

df.pipe(missing_value)
# >> 데이터프레임

df.pipe(missing_count)
# >> age     177
#    fare      0
#    dtype: int64

df.pipe(total_number_missing)
# 177




4.2. 2) 열 재구성

4.2.1. 2-1 열 순서 변경

  • 데이터프레임의 열 순서 변경 : ==DataFrame 객체[재구성한 열 이름의 리스트]==
    • 마지막 범위 값 포함
df = titanic.loc[0:4, 'survived':'age']

 

  • list() : 데이터프레임 열 >> 리스트
df.columns
## index

df.columns.values
## 값들 >> array

list(df.columns.values)
# 리스트

 

  • sorted(columns) : 열 이름 >> 알파벳 순으로 정렬
columns_sorted = sorted(columns)  # 열 이름을 알파벳 순으로 정렬
df_sorted = df[columns_sorted]

 

  • reversed(columns) : 기존 순서의 정반대 역순으로 정렬
columns_reversed = list(reversed(columns))  # 정렬된 열 이름의 리스트 이용
df_reversed = df[columns_reversed]

 

  • columnscusmed : 임의의 순서로 열 이름 재배치
    • 임의의 순서로 열 이름을 재배치한 상태로 데이터프레임 df에서 각 열을 순서에 맞춰서 선택
columns_customed = ['pclass', 'sex', 'age', 'survived']
df_customed = df[columns_customed]



4.2.2. 2-2 열 분리

  • ype() 메소드 : 자료형 변경
    • '연월일' 열의 시간형 데이터를 문자열로 변경
    • ==df.str.split()==
    • 문자열을 split() 메소드를 분리
df['연월일'] = df['연월일'].astype('str')  # 문자열 메소드 사용을 위해 자료형 변경
df['연월일'].str.split('-')  # 문자열을 split() 메소드로 분리

 

  • 시리즈의 문자열 리스트 인덱싱 : ==Series 객체.str.get(인덱스)==
    • str.t()
    • **문자열 리스트의 원소 선택**
df['연'] = dates.str.get(0)
df['월'] = dates.str.get(1)
df['일'] = dates.str.get(2)



4.3. 3) 필터링

4.3.1. 3-1 불린 인덱싱

  • 참/거짓
  • 시리즈 객체에 어떤 조건식을 적용하면 각 원소에 대해 참/거짓을 판별하여 불린(참/거짓) 값으로 구성된 시리즈를 반환

 

  • 데이터프레임 불린 인덱싱 : ==DataFrame 객체[불린 시리즈]==
# 나이가 10대(10~19세)만 추출하시오.
condition = (titanic.age >= 10) & (titanic.age < 20)

# 1번째 방법
titanic[condition]
# 2번째 방법
titanic.loc[condition, :]
# 나이가 10세 미만(0~9세) 또는 60세 이상인 승객의 age, sex, alone 열만 선택

condition = (titanic.age < 10) | (titanic.age >= 60)
titanic.loc[condition, ['age','sex','alone']]



4.3.2. 3-2 isin() 메소드 활용

  • isin() 메소드를 활용한 필터링 : ==DataFrame의 열 객체.isin(추출 값의 리스트)==
    • isin() : 특정 값을 가진 행들을 따로 추출 가능
    • **T/F 반환**
# 함께 탑승한 형제 또는 배우자 수가 3, 4, 5 인 승객만 따로 추출하시오
mask_3 = titanic['sibsp'] == 3
mask_4 = titanic['sibsp'] == 4
mask_5 = titanic['sibsp'] == 5
condition = (mask_3) | (mask_4) | (mask_5)
titanic[condition]
condition = titanic['sibsp'].isin([3,4,5])
titanic[condition]



4.4. 4) 데이터프레임 합치기

4.4.1. 4-1 데이터프레임 연결

  • 데이터프레임 연결 : ==Pandas.concat(데이터프레임의 리스트)==
    • concat()
    • 이어 붙이듯 연결
    • 데이터프레임을 원소로 갖는 리스트를 전달하면 여러 개의 데이터프레임을 서로 연결
    • default : **axis=0** (행 방향으로 연결)
      • aξs=1 : 열 방향으로 연결
    • default : **join = 'outer'** (합집합)
      • jo=r : 교집합
    • ignoredex=True : 기존 행 인덱스를 무시하고 새로운 행 인덱스 설정

![image-20220620190418867](pandas-imgaes/image-20220620190418867.png)

 

![image-20220620190852775](pandas-imgaes/image-20220620190852775.png)

 

pd.concat([df1,df2], axis=1, join='inner')

abcabcd

2 a2 b2 c2 a2 b2 c2 d2
3 a3 b3 c3 a3 b3 c3 d3



4.4.2. 4-2 데이터프레임 병합

  • 데이터프레임 병합 : ==Pandas.merge( df_left, df_right, how='inner', on=None)==
    • mer()
    • 어떤 기준에 의해 두 데이터프레임 병합
    • SQL join 명령과 비슷
    • 기준이 되는 열이나 인덱스를 키(key) - 양쪽 데이터프레임에 모두 존재해야 함
    • default : **on=None** (공통으로 속하는 모든 열을 기준(key)으로 병합)
      • on= : 공통 열 중 'id' 열을 키로 병합
    • default : **how='inner'** (교집합일 경우에만 추출)
      • how=outer : 기준 데이터가 데이터프레임 중 어느 한쪽에만 속하더라도 포함
      • how=ft : 왼쪽 데이터프레임의 키 열에 속하는 데이터 값을 기준으로 병합
        • fton, righton 옵션으로 좌우 데이터프레임에 각각 다르게 키를 지정 가능
      • 어느 한 쪽이라도 데이터가 없는 열에는 NaN값
pd.merge(df1, df2, how='left', left_on='stock_name', right_on = 'name')



4.4.3. 4-3 데이터프레임 결합

  • 행 인덱스 기준으로 결합 : ==DataFrame1.join(DataFrame2, how='left')==
    • 두 데이터프레임의 행 인덱스를 기준으로 결합
    • on=keys옵션을 설정하면 행 인덱스 대신 다른 열을 기준으로 결합
    • dexcol옵션을 적용하여 행 인덱스 설정 가능
    • default : **how='left'** (왼쪽 df의 행 인덱스를 기준으로 결합)
      • how=r : 두 데이터프레임에 공통으로 존재하는 행 인덱스 기준으로 추출
df1.join(df2, how='inner')



4.5. 5) 그룹 연산

  • 1단계) 분할(split) : 데이터를 특정 조건에 의해 분할
  • 2단계) 적용(apply) : 데이터 집계, 변환, 필터링하는데 필요한 메소드 적용
  • 3단계) 결합(combine) : 2단계의 처리 결과를 하나로 결합

4.5.1. 5-1 그룹 객체 만들기(분할 단계)

  • 그룹 연산(분할) : ==DataFrame 객체.groupby(기준이 되는 열)==
    • 데이터프레임의 특정 열을 기준으로 데이터프레임을 분할하여 그룹 객체를 반환
    • tgroup() 메소드를 적용하면 특정 그룹만을 선택할 수 있다.
df = titanic.loc[:,['age','sex','class','fare','survived']]
grouped = df.groupby(['class'])
grouped.get_group('Third')  # 특정 그룹만 선택
grouped.mean() # mean() : 평균
grouped.std()  # std() : 표준편차

 

  • 그룹 연산(분할) : ==DataFrame 객체.groupby(기준이 되는 열의 리스트)==
    • 여러 개의 기준 값을 사용
    • 반환되는 그룹 객체의 인덱스는 다중 구조를 갖음
grouped_two = df.groupby(['class','sex'])
grouped_two.get_group(('Third','female'))  # 특정 그룹만 선택
grouped_two.mean() # >> 멀티 인덱스



4.5.2. 5-2 그룹 연산 메소드(적용 - 결합 단계)

  • 표준편차 데이터 집계(내장 함수) : ==group 객체.std()==
    • 데이터 집계 (aggreagation)
    • mean(), max(), min(), sum(), count(), size(), var(), std(), describe(), info(), first(), last()

 

  • agg() 메소드 데이터 집계 : ==group 객체.agg(매핑 함수)==
def min_max(x):
    return x.max() - x.min()

grouped.agg(min_max)

 

  • 모든 열에 여러 함수 매핑 : ==group 객체.agg([함수1, 함수2, 함수3, ... ])==
grouped.agg(['min','max'])
# sex는 범주형 데이터라 min_max 안됨

 

  • 각 열마다 다른 함수를 매핑 : ==group 객체.agg({'열1' : 함수1, '열2' : 함수2, ...})==
grouped.agg({'fare':['min','max'],
            'age':'mean'})

 

  • 데이터 변환 연산 : ==group 객체.transform(매핑 함수)==
    • tranorm()
    • 그룹 별로 구분하여 각 원소에 함수를 적용하지만 그룹별 집계 대신 각 원소의 본래 행 인덱스와 열 이름을 기준으로 연산 결과를 반환
    • 그룹 연산의 결과를 원본 데이터프레임과 같은 형태로 변형하여 정리
# 그룹 객체의 age 열을 iteration으로 z-score를 계산하여 출력
for key, group in grouped.age:
    group_zscore = (group - grouped.age.mean().loc[key]) / grouped.age.std().loc[key]

 

# z-score 계산하는 사용자 함수 정의
def z_score(x):
    return (x-x.mean()) / x.std()

age_zscore = grouped.age.transform(z_score)

z-score 계산하는 사용자 함수 정의, tranorm() 메소드의 인자로 전달

 

  • 그룹 객체 필터링 : ==group 객체.filter(조건식 함수)==
    • fi<er()
    • 조건이 참인 그룹의 데이터만 추출
# 데이터 개수가 200개 이상인 것만 추출
grouped_filter = grouped.filter(lambda x : len(x) >= 200)

 

  • 범용 메소드 : ==group 객체.apply(매핑 함수)==
    • apply() (메소드)
    • 판다스 객체의 개별 원소를 특정 함수에 일대일로 매핑
    • 사용자가 원하는 대부분의 연산을 그룹 객체에도 적용할 수 있음
    • default : **axis=0**
age_grouped = grouped.apply(lambda x: x.describe())

 

# z-score 계산을 apply()로 해볼까요?

def z_score(x):
    return (x-x.mean()) / x.std()

age_zscore = grouped.age.apply(z_score)  # default : axis=0

 

# 필터링 : age 열의 데이터 평균이 30보다 작은 그룹만을 필터링하여 출력

age_filter = grouped.apply(lambda x: x.age.mean() < 30)

for x in age_filter.index:
    if age_filter[x] == True:
        print(grouped.get_group(x))
        print('\n')



4.6. 6) 멀티 인덱스

  • loc 인덱서
  • xs 인덱서
# class 열, sex 열을 기준으로 분할
grouped = df.grouped(['class','sex'])

# 그룹 객체에 연산 메소드 적용
gdf = grouped.mean()

# class : First >> sex : female
gdf.loc[('First','female')]

# sex값이 male인 행 선택, 출력
gdf.xs('male', level='sex')




7) 피벗

  • πvottab()
  • 엑셀에서 사용하는 피벗테이블과 비슷한 기능
# 행, 열, 값, 집계함수 (default: 평균)

df3 = pd.pivot_table(df,                # 피벗할 데이터프레임
               index=['class', 'sex'],  # 행 위치에 들어갈 열
               columns='survived',      # 열 위치에 들어갈 열
               values= ['age','fare'],  # 데이터로 사용할 열
               aggfunc=['mean', 'max']) # 데이터 집계 함수

# Ipython Console 디스플레이 옵션 설정
pd.set_option('display.max_columns', 10)  # 출력할 열의 최대 개수

 

  • xs인덱서 사용
    • default : **행 인덱스**
    • default : **axis=0**
      • 열 선택 : aξs=1
df3.xs('male', level='sex')
# sex 레벨에서 남성 승객 데이터만 추출 

df3.xs(('Second','male'), level=[0, 'sex'])
# second, male인 행 선택 
df3.xs(('max', 'fare', 0),
      level=[0,1,2], axis=1)
# max, fare, survived=0 인 데이터 선택 
1. 5. 데이터 사전 처리1.1. 1) 누락 데이터 처리1.2. 2) 중복 데이터 처리1.3. 3) 데이터 표준화 (***)1.3.1. 3-1 단위 환산1.3.2. 3-2) 자료형 변환1.4. 4) 범주형(카테고리) 데이터 처리1.4.1. 4-1 구간 분할1.4.2. 4-2 더미 변수1.5. 5) 정규화1.6. 6) 시계열 데이터1.6.1. 6-1 다른 자료형을 시계열 객체로 변환1.6.2. 6-2 시계열 데이터 만들기1.6.3. 6-3 시계열 데이터 활용2. 6. 데이터프레임의 다양한 응용2.1. 1) 함수 매핑2.1.1. 1-1 개별 원소에 함수 매핑2.1.2. 1-2 시리즈 객체에 함수 매핑2.1.3. 1-3 데이터프레임 객체에 함수 매핑2.2. 2) 열 재구성2.2.1. 2-1 열 순서 변경2.2.2. 2-2 열 분리2.3. 3) 필터링2.3.1. 3-1 불린 인덱싱2.3.2. 3-2 isin() 메소드 활용2.4. 4) 데이터프레임 합치기2.4.1. 4-1 데이터프레임 연결2.4.2. 4-2 데이터프레임 병합2.4.3. 4-3 데이터프레임 결합2.5. 5) 그룹 연산2.5.1. 5-1 그룹 객체 만들기(분할 단계)2.5.2. 5-2 그룹 연산 메소드(적용 - 결합 단계)2.6. 6) 멀티 인덱스2.7. 7) 피벗3. 5. 데이터 사전 처리3.1. 1) 누락 데이터 처리3.2. 2) 중복 데이터 처리3.3. 3) 데이터 표준화 (***)3.3.1. 3-1 단위 환산3.3.2. 3-2) 자료형 변환3.4. 4) 범주형(카테고리) 데이터 처리3.4.1. 4-1 구간 분할3.4.2. 4-2 더미 변수3.5. 5) 정규화3.6. 6) 시계열 데이터3.6.1. 6-1 다른 자료형을 시계열 객체로 변환3.6.2. 6-2 시계열 데이터 만들기3.6.3. 6-3 시계열 데이터 활용4. 6. 데이터프레임의 다양한 응용4.1. 1) 함수 매핑4.1.1. 1-1 개별 원소에 함수 매핑4.1.2. 1-2 시리즈 객체에 함수 매핑4.1.3. 1-3 데이터프레임 객체에 함수 매핑4.2. 2) 열 재구성4.2.1. 2-1 열 순서 변경4.2.2. 2-2 열 분리4.3. 3) 필터링4.3.1. 3-1 불린 인덱싱4.3.2. 3-2 isin() 메소드 활용4.4. 4) 데이터프레임 합치기4.4.1. 4-1 데이터프레임 연결4.4.2. 4-2 데이터프레임 병합4.4.3. 4-3 데이터프레임 결합4.5. 5) 그룹 연산4.5.1. 5-1 그룹 객체 만들기(분할 단계)4.5.2. 5-2 그룹 연산 메소드(적용 - 결합 단계)4.6. 6) 멀티 인덱스
복사했습니다!