데브코스 28일차 - 데이터프레임 기초, 활용

kiki·2024년 3월 28일
0

데브코스

목록 보기
7/17

키워드

데이터프레임

데이터프레임 기초

생성

member = {
	‘Attack’: [111,222,333], #하나의 시리즈로 여겨짐
	‘Defence’: [444,555,666],
	‘Luck’: [777,888,999]
}
member_df = pd.DataFrame(member)
  • 인덱싱 해서 단일 컬럼에 접근한다면 시리즈가 반환됨

    • 닷(.)을 이용해서 접근할 수도 있으나 이는 지향되지 않음
    • member_df.shape 과 같은 함수와 혼동될 수 있음 (만약 column명이 shape라면)
  • 가로가 인덱스, 세로가 컬럼 명

  • member_df = pd.DataFrame(data=data, columns=columns)

    • 이중 리스트를 data로, 컬럼 명을 담은 리스트를 columns로 넘겨줘서 데이터프레임을 만들고자 함
    • 근데 여기서 data에 리스트 하나가 행을 의미
    • columns과 index를 넘겨주지 않는다면 rangeIndex가 디폴트로 설정됨 (df.columns, df.index)

속성

df.shape → 행령 크기(모양)을 알 수 있음

df.size → 크기!!를 알 수 있음

df.info() → info는 메소드이기 때문에 .. 데이터 프레임 정보를 알려줌

df.values → 값 만 뽑아준다.

df.dtypes → 인덱스와 type으로 이루어진 시리즈를 반환받음

df.index → 인덱스 정보

df.columns → 컬럼 정보

df.axes → 각 축이 어떻게 구성되어있는지를 보여줌

메소드 (주로 집계함수)

df.sum() → 각 열(시리즈)에 대한 합. sum(시리즈)에 sum하면 전체의 합이 나옴

df.sum(axis=0) → 열에 대한 합 (디폴트 값이 axis=0, index)

df.sum(axis=1) → 수평 방향으로 합. 즉 하나의 레코드 값들을 합함

max, min, mean, median, prod(곱) 모두 axis를 적용해서 사용 가능

df.count()로 null 값이 아닌 데이터 수를 셀 수 있다.

  • usecols의 순서가 가져오는 데이터프레임 순서에 적용되지 않음
    • movie_df[cols] 하면 원하는 순서로 데이터프레임을 가져올 수 있다.
    • movie_df[[열1, 열2, 열3]]으로 가져오는 것
  • info로 간단한 정보를 출력해 결측치를 확인해볼 수 있다.
  • describe를 이용해 데이터 값 요약(mean, max, min 등)을 볼 수 있다.
    • 근데 만약 숫자인데 object로 저장되어있으면 describe에서 볼 수 없음
    • 형변환이 필요!
  • 형변환
    • gross(수익) 열이 콤마를 포함하는 문자(object) type을 가짐
    • movie_df[’Gross’] = movie_df[’Gross’].str.replace(’,’, ’’)
    • movie_df[’Gross’].fillna(0, inplace=True) → nan 값을 0으로 채움
    • movie_df[’Gross’] = movie_df[’Gross’].astype(’int64’)
  • describe
    • movie_df.describe(percentiles=[.2, .4, .6, .8]).round(1)
    • describe을 통해 볼 수 있는 정보에 퍼센테이지를 추가할 수 있다.
  • df에 집계함수를 적용하면 오류가 날 때가 있음
    • 문자 컬럼때문에 나는 오류
    • numeric_only=Ture 인자를 넘겨줘서 숫자 타입의 컬럼에만 집계함수를 적용하겠다는 의미
  • quantile (분위수)
    • describe의 percentiles와 동일
    • movie_df.quantile(q=.5, numeric_only=True).round(1) → 숫자 데이터에 50% 지점의 값들을 확인할 수 있음
  • include
    • include=’all’로 전체 데이터의 describe을 볼 수 있었
    • df.describe(include=[’O’]) 처럼 인자를 넘겨줘서 문자 타입 컬럼의 describe만 볼 수 있음

정렬

  • nlargest
    • movie_df.nlargest(n=5, columns=['IMDB_Rating'])
    • IMDB_Rating 기준으로 큰 5개의 데이터를 조회하겠다! 라는 뜻
    • movie_df.sort_values(by=’IMDB_Rating’, ascending=False).head(5)과 동일한 작용
  • nsmallest()
    • nlargest와 동일. 작은 순으로 보여줌
    • movie_df.nsmallest(n=5, columns=['IMDB_Rating','Meta_score'])
    • 위와 같이 작성해 1순위 정렬 기준, 2순위 .. 를 설정해줄 수 있음
  • keep=
    • 중복된 값이 있는 경우.
    • ‘all’ = n개를 넘더라도 동일한 최솟값, 최대값이 있다면 보여줘라
    • ‘first’, ‘last’ = 먼저 있는 값, 나중에 있는 값을 보여줘라
    • movie_df.nsmallest(n=5, columns=['IMDB_Rating','Meta_score'], keep='all')
  • sort_values()
    • data frame을 sort_values() 할 때는 by로 정렬 기준이 될 컬럼을 넘겨줘야함
    • movie_df.sort_values(by=[''IMDB_Rating','Meta_score'], ascending=False)

인덱스 제어

  • set_index()
    • movie_df.set_index(’Series_Title’)
    • 데이터의 컬럼을 인덱스로 사용!
    • 특정 컬럼을 인덱스로 설정한다면 기존 컬럼은 삭제됨. set_index의 drop 인자가 True기 때문
  • df.index.name
    • movie_df.index.name = ‘Title’
    • 인덱스의 컬럼명(?)을 설정
  • reset_index
    • movie_df.reset_index()
    • 인덱스를 RangeIndex로 초기화해준다.
    • drop 인자가 False이므로 인덱스가 없어지지 않고 컬럼으로 넘겨진다.
  • index_col로 열 지정
    • pd.read_csv(’~.csv’, usecols=cols, index_col=’~’)
    • 이 때 index_col로 설정한 컬럼이 usecols에도 포함되어있어야함

행렬 삭제

  • drop
    • 데이터 드롭하는 방법
    • 열 삭제: movie_df.drop(columns=[’Poster_Link’, ‘Overview’], inplace=True)
      • columns 지정 안하고 axis=1(열)로 지정해줘서 삭제할 수 있다.
    • 행 삭제: movie_df.drop(labels=1, inplace=True) → labels도 리스트로 넘겨줄 수 있다.
      • labels 지정 안하고 리스트 넘겨줘도 행을 삭제해줌
    • errors=’ignore’로 설정해 오류를 내지 말라고 할 수 있음
  • del
    • del movie_df[’Runtime’]을 이용해 열 삭제를 할 수도 있음

열 조회와 추가

  • get 함수를 이용해 안전하게 열을 조회할 수 있다.
  • 열 추가
    • movie_df[’new’] = False → 일련적으로 False 값이 들어감
    • movie_df.insert(loc=5, column=’My_score’, value=None)
      • 컬럼이 들어갈 위치, 이름, 초기값 등을 지정해서 열을 추가해줄 수 있음
      • value에 시리즈 데이터를 넘겨줘서 값을 지정할 수도 있음
      • 사이즈가 다르더라도 시리즈를 넘겨준다면 index에 맞춰 추가됨

결측치 제어

  • .dropna()
    • nan 유형 데이터를 drop한다
    • movie_df.dropna() → 행에 nan이 하나라도 있으면 row 삭제
    • movie_df.dropna(axis=1) → nan 값을 포함하는 컬럼 삭제
    • how 인자: ‘any’ (하나라도 있으면), ‘all’ (전부 nan값이면)
    • subset 인자: 특정 열의 na만 확인
      • movie_df.dropna(subset=[’Certificate’]) → subset의 nan 데이터만 확인
  • .fillna()
    • df.fillna(value=0) → 0으로 결측치를 대체하겠다
    • method 인자: bfill(다음 행의 값), ffill(마지막으로 관찰된 유효한 값), None
    • limit 인자: 결측치 대체 횟수 지정

과제

  • 집계함수 사용시엔 na 값은 무시됨
  • nlargest, nsmallest를 이용해 가장 작은 값, 큰 값을 뽑을 수 잇음

데이터프레임 활용

  • titanic_df = titanic_df.sort_index(key=lambda x:x.str.lower())

    • sort하면 대문자가 앞에 오고 소문자가 뒤에 오기 때문에 이러한 대/소문자 구분 없이 알파벳 순으로 정렬하고자 할 때 key를 사용해 sort해주면 된다.
  • .loc[]

    • 하나의 레이블(인덱스의 값), 레이블의 리스트, 레이블의 범위로 된 슬라이스(end 값 포함, 이건 loc 안써도 되긴 함), 축과 길이가 같은 bool 리스트 들이 인자로 들어갈 수 있음
    • 반환을 데이터프레임으로 받고싶다면 리스트로 인자 전달
    • 오류를 처리하고싶다면 if else문이나, try except문 사용
  • .duplicated()

    • titanic_df.index.duplicated() → 중복 여부에 따라 bool 타입의 시리즈 반환
    • titanic_df[titanic_df.index.duplicated()] 하면 인덱스로 중복값을 갖는 데이터 조회 가능
      • 근데 중복되는 값 중 나머지 하나만 조회됨. 즉 첫번째로 나오는 데이터는 중복으로 인지하지 않고, 다음부터 나오는 값을 중복으로 인지하는 것
      • keep 인자를 조정해주면 됨
        • first(첫번째 등장하는 값을 제외하고 중복값으로 표시), last(마지막 등장하는 값을 제외하고 중복값으로 표시), false(전부 다 중복값으로 표시)
      • titanic_df[titanic_df.index.duplicated(keep=False)] 처럼 keep을 False로 설정해 모두 중복값으로 표시

특정 승객의 등급을 확인하고싶다면?

titanic_df[’승객 이름’, ‘pclass’] → 인덱스와 컬럼이 인자로 들어감

titanic_df[’승객 이름’, [‘pclass’, ‘fare’]] → 두개의 컬럼 값을 확인할 수 있음

titanic_df[[[’승객 이름’], [‘pclass’, ‘fare’]]] → 결과를 데이터프레임으로 받기

  • iloc

    • iloc은 인덱스 위치를 참조하고, loc은 인덱스를 참조한다.

      • df.iloc[-1]은 가능하지만 df.iloc[-1]은 불가하다 (인덱스로 -1 값을 갖지 않는 경우)
    • iloc을 지향하는 것은 지양해라…

      • 유실된 데이터에 대해 조회가 가능해질 수 있기 때문에
    • titanic.iloc[5:11] → 슬라이싱에선 마지막 값도 포함

    • iloc[index_position] → series

    • iloc[[index_position]] → DataFrame

    • iloc[[index_position1, 2, 3]] → DataFrame

    • iloc[index_position, column_position] → 스칼라

    • iloc[[index_position1, 2, 3], column_position] → series (차원 축소)

    • iloc[[index_position1, 2, 3], [column_position]] → DataFrame

    • iloc[index_position, [column_position]] → series (차원 축소)

    • iloc[:, [column_position1, 2]] → DataFrame

      💡 유의미하고 명확하게 사용하게 되는 건 loc이다. 즉 loc의 사용을 지향하자
  • Broadcasting

    • 크기나 모양이 다를 때의 처리 방식을 정하는 것
    • numpy와 pandas에서 broadcating이 다름
      • numpy는 스트레치해서 값을 계산하고, pandas는 각각 처리 후 반영이 어려운 곳은 결측치로 처리
    • df.sub(s4, axis=’index’) → dataframe에서 s4(시리즈, 열)를 sub 해주면 스트레칭이 일어남
      • 시리즈는 무조건 일차원이기 때문에
      • 데이터프레임 끼리의 sub에선 일어나지 않음 → 원치 않는 결과가 나온다.
    • df1.sub(s5) → s5가 행 값을 갖는 시리즈일 때 이 연산에서 stretch가 발생한다
    • 즉 세로 방향의 연산은 상관 없지만, 가로 방향의 연산은 axis를 지정해줘야함
    • titanic[’fare’] * 0.7 → 차원이 맞지 않기 때문에 연산이 어렵지만 stretch가 일어남
  • 조건문

    • survived가 1인 사람 뽑아보기
      • survived_mask = titanic[’survived’] == 1
      • titanic[survived_mask]
    • 다중 조건문
      • 마스크를 비트연산자로 묶어 다중의 조건을 사용하기 (&, |, ~)

      • titanic[male_mask & old_mask] → 같은 차원, 크기의 시리즈니 broadcasting이 발생하지 않음

        1_class_mask = titanic[’pclass’]==1
        survived_mask = titanic[’survived’]==1
        under_fifteen = titanic[’age’]<15
        female_mask = titanic[’sex’]==’female
        fare_maks = titanic[’fare’]250
        
        titanic[1_class_mask & survived_mask & female_mask]
        titanic[fare_mask & under_fifteen & survived_mask]
        titanic[(femal_mask | uder_fifteen) & survived_mask
  • 범위 지정 필터링 between

    • series.between(left, right, inclusive=~)

    • inclusive는 끝 값을 포함할 것인지, left, right, both, neither

      upper_20_mask = titanic['age'] >= 20
      lower_30_mask = titanic['age'] <= 30
      titanic[upper_20_mask & lower_30_mask]
      
      age_20s_mask = titanic['age'].between(20, 30, inclusive='both')
      titanic[age_20s_mask]
  • 결측치를 제어해서 조건문을 단순화 시키기

    • .isin() → 각 요소가 특정 값들에 속하는지 여부

      • titanic[’pclass’].isin([1,2]) → 비트연산자와 동일하게 모든 데이터에 대해 bool type의 시리즈가 반환됨
    • .isnull()

      • na 값에 대해 true를 반환
    • .notnull()
      - na가 아닌 값에 대해 true를 반환

      unknown_age_mask = titanic['age'].isnull() -> 나이가 식별되지 않는 사람(결측치)
      known_age_mask = titanic['age'].notnull() -> 나이가 식별된 사람
  • 행렬 인덱스 네이밍 변경

    • titanic.columns → 열 목록 조회
    • 컬럼명 변경
      • titanic.rename(columns={’pclass’:’class’, ‘cost’:’fare’}, inplace=True) → pclass 컬럼의 이름 변경
        • titanic.rename({’pclass’:’class’, ‘cost’:’fare’}, axis=1)로 columns 안쓰고 axis 지정해줘도 됨
      • titanic.columns = 리스트 → 이렇게 해서도 변경 가능!
    • 인덱스명 변경
      • titanic.rename(index={Allen, Miss, Elisabeth Walton’:’Allen’})
    • 인덱스 이름 변경 → titanic.index.name = ‘Passengers’
    • 컬럼 이름 변경 → titanic.columns.name = ‘Information’

내 생각

  • 과제에서 이상한 부분이 있었어서 지피티에게 물어봤다. 인자로 리스트를 넘겨줄 때랑 문자열을 넘겨줄때, 저러한 이유로 return에 차이가 있다고 한다.
  • 즉 리스트로 넘겨주면 그 열들을 기준으로 그룹화해서 counts를 하기 때문에 차이가 있는 것.

0개의 댓글