데브코스 29일차 - 데이터프레임 심화

kiki·2024년 3월 28일
0

데브코스

목록 보기
6/17

키워드

데이터 프레임

데이터셋

  • pd.read_csv(”marketing_campaign.csv”, **sep=’\t’**)
    • 디폴트는 쉼표인데 이 데이터셋은 탭으로 구분되어있어 구분자(sep)를 지정해줘야함

apply

  • customer.insert(1, ‘Age’, 2021-customer[’birthYear’]) → 원하는 위치에 새로운 컬럼 insert
  • customer[’Age_Group’] = customer[’Age’].apply(classify_age) → age 컬럼에 classify_age 함수를 적용
  • data = customer.pop(’Age_Group’)customer.insert(2, ‘Age_Group’, data’)
  • customers.apply(total_meat_fish, axis=1) → 열 방향으로 함수 적용. 그니까, total_meat_fish 함수가 각 레코드를 인자로 받는다.
# 수입을 달러에서 원화로 

customers['Income'].apply(lambda x: x*1312) # 시리즈
customers.apply(lambda x: x['Income']*1312, axis=1) # 데이터프레임

# 둘이 같은 결과를 냄
  • 시리즈에 적용할 땐
    def clf_income(income):
        if income>=60000:
            return '고임금'
        elif income>=30000:
            return '평균임금'
        else:
            return '저임금'
    • 이렇게 함수 input이 하나의 값이라고 생각하면 되는거고,
  • 데이터프레임에 적용할 땐
    def age_group(row):
    	if row['age']>80:
    		return '노년'
    ~~
    • 이렇게 함수의 input이 행이라고 생각하면 됨
    • 그리고 이 경우엔 axis=1로 지정

map

  • map
    • people[’DriverLicense’].map({True: ‘Yes’, False: ‘No’})
    • 매핑 안된 값은 NA 데이터로 만듦 → 모든 데이터가 매핑되도록 map 함수를 사용할 것
    • 아래 나올 replace와 유사하다.
  • applymap
    • 모든 요소에 apply를 할 수 있음. 데이터프레임에만(not 시리즈) 적용 가능
    • people.applymap(type) → df의 모든 데이터의 type이 나옴
    • people.applymap(str) → 모든 데이터의 타입을 object(string)으로
      • people.astype(str)으로 해도 모든 데이터의 형변환이 되긴 한다.
customers['Kidhome'] = customers['Kidhome'].map({0:'자녀 없음', 1:'외동', 2:'다자녀'})
# customers.astype(str).applymap(uppercase)
customers.applymap(str).applymap(uppercase)

astype

  • int8, int 16, int64
    • unsigned면 양수만
    • 데이터 사이즈에 맞춰 적당한 타입을 지정해주는 게 메모리를 줄이는 데 도움을 줄 수 있다.
    • 자녀 수 같은 데이터들은 int8로 지정해 용량을 줄여줌
      • customers[’Kidhome’] = customers[’Kidhome’].astype(’uint8’)
      • 지금은 데이터 사이즈가 크지 않아 별 차이없지만, 데이터가 실무에서처럼 커진다면 이러한 변경은 메모리를 많이 아낄 수 있음

replace

  • customers[’Marital_Status’].replace({’Alone’:’Single’, ‘Absurd’:’Single’, ‘YOLO’:’Single’})
    • 특정 값들을 대체
    • map과 유사하다
  • customers[’Marital_Status’].replace([’Alone’, ‘Absurd’, ‘YOLO’], ‘Single’)
    • 특정 값 모음(리스트)를 하나의 값으로 대체
    • 이때는 딕셔너리 형태가 아니다.
  • df.replace(~)
    • 모든 요소에 대해 replace 진행

where

  • customers.where(customers[’kidhome’]≥2)
    • 조건에 맞지 않는 데이터는 NA를 반환
      • other 인자에 문자열을 넘겨줘서 NA 말고 다른 데이터로 대체할 수 있다.
      • customers.where(customers[’kidhome’]≥2, other='---')
    • 이 코드에 dropna()를 적용하면 조건을 만족하는 데이터만 조회됨

agg (aggregation)

  • 특정한 부분에 대해서만 집계

  • customers.agg({’Income’:max, ‘Kidhome’:’mean’})
    • income의 max값과 kidhome의 mean값이 시리즈로 반환됨
    • 만약 두 컬럼에 max값을 보고싶다면 customers[['Income','Kidhome']].agg('max')처럼 적용할 수도 있다.
  • customers.agg({’Income’:[’max’, ‘min’, ‘std’], ‘Kidhome’:’mean’})
    • 함수를 리스트로 여러개 넘겨줄 수도 있다.
    • 웬만하면 문자열로 함수를 넘겨주자!
    • 반환 타입이 데이터프레임! -> 차원수가 늘어났으니까
  • customers.agg(’max’)
    • 모든 컬럼에 적용. 즉 모든 컬럼에서 max값을 뽑아볼 수 있다.
  • 문자열에 mean 적용 → 에러남
    • 대처 1: 문자형 열 드롭하고 적용
    • 대처 2: select_dtypes(inclue=’number’)를 사용해 숫자형 열만 사용
      • customers.select_dtypes(include='number').agg('max)
💡 웬만하면 agg에 함수를 넘겨줄 땐 문자열(이름)으로 넘겨주자.

copy, equals

  • .equals()
    • customers.equals(customers_copy)
    • 두 데이터프레임이 같은지 확인하는 함수
    • customers == customers_copy로 비교하면 각 요소별로 ==연산이 돼서 불리안 타입의 데이터프레임을 결과값으로 받는다.
  • 주소 비교
    • id(customers) 하면 해당 데이터프레임의 주소를 확인할 수 있음
    • customers is customers_copy 하면 두 데이터프레임의 주소가 같은지 확인할 수 있다.
  • 시리즈 값 변경
    • tmp = customers[’Marital_Status’]
    • tmp[0:3] = ‘OOO’
      • 원본에 적용됨! 왜냐면 tmp는 customers[’Marital_Status’]를 참조(not copy)한 것이기 때문

멀티 인덱싱

  • read_csv 할 때부터 index_col에 리스트를 넘겨 설정해줌
    • index_col = [’Marital_Status’,’ID’]
  • set_index() 사용
    • customers.set_index([’Marital_Status’,’ID’])
    • 인덱스를 확인(.index)하면 튜플 형태로 확인됨
  • customers.index.get_level_values(0) → 첫번재 인덱스만 시리즈로 확인
  • customers.swaplevel()
    • 인덱스 위치를 변경
  • customers.sort_value(”Marital_Status”) 해서 각 그룹별로 정렬해 볼 수 있음
  • customers.loc[’Single’] → 즉 인덱스로 ‘single’ 값을 갖는 데이터 조회
  • customers.loc[(’Single’, 5524), ‘Income’] 두 개의 인덱스를 사용해 하나의 특정 값을 조회
  • customers.sort_index(lavel ='Marital_Status',inplace=True)
    • 인덱스를 sort할 때, sort할 레벨의 인덱스를 선택해줄 수 있다.
  • customers.loc[[’Single’, ‘Alone’, ‘Absurd’, ‘YOLO’ ]]
  • customers.loc[([’Single’, ‘Alone’, ‘Absurd’, ‘YOLO’ ], [5524, 2114, 92, 4369, 11133]), :]
    • 두 개의 인덱스를 지정해주고, 모든 열을 가져온다는 의미에서 : 를 마지막 인자로 넘겨줌
  • customers.loc[:, 2114, :]
  • 특정 레벨의 인덱스 생략하는 방법
    • customers.loc[(**slice(None)**, 2114), ‘Income’]
    • customers.loc[pd.IndexSlice[:, 2114], ‘Income’]

내 생각

  • 시리즈에 적용하는 함수와, 데이터프레임에 적용하는 함수에 차이점을 인지하자!
    • apply 함수처럼 데이터 프레임에 사용되는 apply엔 axis인자가 있는데 시리즈에 사용되는 apply엔 axis인자가 없는 것처럼 이를 인지하고 사용할 것
  • 멀티인덱싱이 조금 많이 복잡한 것 같다.
  • 수업을 듣고 실습을 혼자 진행해보자
    • 보는거랑 직접 써보는거랑 많이 다르다.

0개의 댓글