Pandas 심화

Updated:

조건으로 검샘하기

  • import array와 마찬가지로 masking 연산이 가능하다
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(5, 2), columns = ['A','B'])
#   A	B
# 0	0.082643	0.060151
# 1	0.458029	0.336073
# 2	0.542312	0.850756
# 3	0.308405	0.878746
# 4	0.698897	0.393805

df['A'] < 0.5
# 0     True
# 1     True
# 2    False
# 3     True
# 4    False
# Name: A, dtype: bool
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(5, 2), columns = ['A','B'])
df[(df["A"] < 0.5) & (df["B"] > 0.3)]
df.query("A < 0.5 and B > 0.3")
#   A	B
# 0	0.146824	0.988963
# 3	0.167327	0.744833
  • 문자열이라면 다른 방식으로도 조건 검색이 가능하다
df = pd.DataFrame([["Dog", "Happy"],
                   ["Cat", "Sam"],
                   ["Cat", "Toby"],
                   ["Pig", "Mini"],
                   ["Cat", "Rocky"]], columns = ['Animal','Name'])
df["Animal"].str.contains("Cat")
df.Animal.str.match("Cat")
# 0    False
# 1     True
# 2     True
# 3    False
# 4     True
# Name: Animal, dtype: bool

함수로 데이터 처리하기

  • apply를 통해서 함수로 데이터를 다룰 수 있다
df = pd.DataFrame(np.arange(5), columns=["Num"])
def square(x):
  return x*2
df["Num"].apply(square)
# 0    0
# 1    2
# 2    4
# 3    6
# 4    8
# Name: Num, dtype: int64

df["square"] = df.Num.apply(lambda x: x**2)
#   Num  square
# 0    0       0
# 1    1       1
# 2    2       4
# 3    3       9
# 4    4      16
  • 예제
df = pd.DataFrame(columns=["phone"])
df.loc[0] = "010-1234-1235"
df.loc[1] = "공일공-일이삼사-1235"
df.loc[2] = "010.1234.일이삼오"
df.loc[3] = "공1공-1234.1이3오"
df["preprecess_phone"] = ''
#   phone	preprecess_phone
# 0	010-1234-1235	
# 1	공일공-일이삼사-1235	
# 2	010.1234.일이삼오	
# 3	공1공-1234.1이3오	

def get_preprocess_phone(phone):
  mapping_dict = {
    "공" : "0",
    "일" : "1",
    "이" : "2",
    "삼" : "3",
    "사" : "4",
    "오" : "5",
    "-" : "",
    "." : ""
  }
  for key, value in mapping_dict.items():
    phone = phone.replace(key, value)
  return phone
df["preprecess_phone"] = df["phone"].apply(get_preprocessed_phonenumber)
#   phone	preprecess_phone
# 0	010-1234-1235	01012341235
# 1	공일공-일이삼사-1235	01012341235
# 2	010.1234.일이삼오	01012341235
# 3	공1공-1234.1이3오	01012341235
  • replace: apply 기능에서 데이터 값만 대체 하고 싶을때
df = pd.DataFrame(["Male","Male","Female","Femaile","Male"],columns=["Sex"])
#   Sex
# 0    Male
# 1    Male
# 2  Female
# 3  Female
# 4    Male

df.Sex.replace({"Male": 0, "Female": 1})
df.Sex.replace({"Male": 0, "Female": 1}, inplace = True)
# 0    0
# 1    0
# 2    1
# 3    1
# 4    0
# Name: Sex, dtype: int64

그룹으로 묶기(groupby)

  • 간단한 집계를 넘어서서 조건부로 집계하고 싶은 경우
df = pd.DataFrame({'key':['A', 'B', 'C', 'A', 'B', 'C'],
  'data1' : [1, 2, 3, 1, 2, 3], 'data2': np.random.randint(0, 6, 6)})
df.groupby('key')
# <pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001CA2C72CCC8>

df.groupby('key').sum()
#   data1	data2
# key		
# A	2	5
# B	4	2
# C	6	5

df.groupby(['key','data1']).sum()
#     data2
# key	data1	
# A	1	5
# B	2	2
# C	3	5

aggregate

  • groupby를 통해 집계를 한번에 계산하는 방법
df.groupby('key').aggregate(['min',np.median, max])
#         data1	data2
#   min	median	max	min	median	max
# key						
# A	1	1	1	1	2.5	4
# B	2	2	2	0	1.0	2
# C	3	3	3	0	2.5	5

df.groupby('key').aggregate({'data1':'min', 'data2':np.sum})
#   data1	data2
# key		
# A	1	5
# B	2	2
# C	3	5

filter

  • groupby를 통해서 그룹 속성을 기준으로 데이터 필터링
df = pd.DataFrame({'key':['A', 'B', 'C', 'A', 'B', 'C'],
  'data1' : [1, 2, 3, 1, 2, 3], 'data2': np.random.randint(0, 6, 6)})
df.groupby('key')
#   key	data1	data2
# 0	A	1	4
# 1	B	2	4
# 2	C	3	4
# 3	A	1	3
# 4	B	2	2
# 5	C	3	4

def filter_by_mean(x):
  return x['data2'].mean() > 3
df.groupby('key').mean()
#   data1	data2
# key		
# A	1	3.5
# B	2	3.0
# C	3	4.0

df.groupby('key').filter(filter_by_mean)
#   key	data1	data2
# 0	A	1	4
# 2	C	3	4
# 3	A	1	3
# 5	C	3	4

apply

  • groupby를 통해서 묶인 데이터를 함수 적용
df.groupby('key').apply(lambda x: x.max() - x.min())
# 	data1	data2
# key		
# A	0	1
# B	0	2
# C	0	0

get_group

  • groupby롤 묶인 데이터에서 key값으로 데이터를 가져올 수 있다
df = pd.read_csv("./univ.csv")
df.head()
#   시도      학교명
# 0 충남  충남도립청양대학
# 1 경기  한국복지대학교
# 2 경북  가톨릭상지대학교
# 3 전북  군산간호대학교
# 4 경남  거제대학교

df.groupby("시도").get_group("충남")
#   시도      학교명
# 0 충남  충남도립청양대학
# 44 충남  신성대학교
# 60 충남  백석문화대학교
# 67 충남  혜전대학교
# 92 충남  아주자동차대학
# 112 충남  천안연암대학

len(df.groupby("시도").get_group("충남"))
# 94

MultiIndex

  • 인덱스를 계층적으로 만들 수 있다
df = pd.dataFrame(
  np.random.randn(4, 2),
  index = [['A', 'A', 'B', 'B'], [1, 2, 1, 2]],
  columns = ['data1', 'data2']
)
#   data1	data2
# A	1	-0.096399	-1.648663
# 2	0.594642	-1.407714
# B	1	1.058022	0.920752
# 2	0.317844	0.754203
  • 열 인덱스도 계층적으로 만들 수 있다
df = pd.DataFrame(
  np.random.randn(4, 5),
  columns=[["A", "A", "B", "B"], ["1", "2", "1", "2"]]
)
#       A	B
#   1	2	1	2
# 0	0.098990	0.215629	0.541086	-0.396231
# 1	-1.281989	0.998911	0.545508	-0.542915
# 2	-0.288780	1.242643	0.045207	0.490949
# 3	-0.271796	-0.404544	0.654215	0.664623
  • 다중 인덱스 컴럼의 경우 인덱싱은 계층적으로 한다
  • 인덱스 탐색의 경우에는 loc, iloc를 사용가능하다
df["A"]
#   1	2
# 0	0.098990	0.215629
# 1	-1.281989	0.998911
# 2	-0.288780	1.242643
# 3	-0.271796	-0.404544

df["A"]["1"]
# 0    0.098990
# 1   -1.281989
# 2   -0.288780
# 3   -0.271796
# Name: 1, dtype: float64

pivot_table

  • 데이터에서 필요한 자료만 뽑아서 새롭게 요약
  • 분석 할 수 있는 기능 엑셀에서의 피봇 테이블과 같다
  • index는 행 인덱스로 들어갈 key
  • column에 열 인덱스로 라벨링될 값
  • value에 분석할 데이터
# use titanic데이터
df.pivot_table(
  index='sex', columns = 'class', values='survived',
  aggfunc = np.mean
)
# class   First  Second  Third
# sex
# female  0.968085 0.921053 0.500000
# male    0.368852 0.157407 0.135447

df.pivot_table(
  index = "월별", columns='내역', values = ['수입','지출'])
#       수입               지출
# 내역  관리비 교통비 월급  관리비 교통비 월급
# 월별
# 201805  0 0 400000  200000  50000 0
# 201806  0 0 500000  300000  100000  0
# 201807  0 0 600000  250000  150000  0

예제

남자 어린이와 여자 어린이의 평균 연령을 표로 출력

import pandas as pd import numpy as np

def main():
    # 파일을 읽어서 코드를 작성해보세요
    # 경로: "./data/the_pied_piper_of_hamelin.csv"
    df = pd.read_csv("./data/the_pied_piper_of_hamelin.csv")
    children = df[df["구분"] == "Child"]
    #print(children.groupby("일차").mean())

    df2 = children.pivot_table(index='일차', columns ='성별', values = "나이", aggfunc = np.mean)
    print(df2)
    # 성별    Female      Male
    # 일차                    
    # 3   9.500000  9.000000
    # 4   9.000000  6.333333
    # 5   8.666667  8.833333
    # 6   9.411765  7.846154
    # ==========================================
    for name in childre["이름"].unique():
      print(name)
    # 따라간아이들의 이름을 중복없이 뽑는다  
    
if __name__ == "__main__":
    main()

Leave a comment