Pandas
표 형태(스프레드 시트 등)의 데이터 분석에 효과적인 파이썬 라이브러리

import pandas as pd


CSV
표 형태의 데이터를 대표하는 일반적인 방식으로, 쉼표로 값을 분류

data = pd.read_csv("weather_data.csv")    # 판다스로 CSV 파일 읽기

weather_data.csv
day,temp,condition
Monday,12,Sunny
Tuesday,14,Rain
Wednesday,15,Rain
Thursday,14,Cloudy
Friday,21,Sunny
Saturday,22,Sunny
Sunday,24,Sunny

Table

Pandas의 DataFrame 클래스 전체를 출력할 수 있다.

print(data)     # 데이터프레임 출력(첫 번째 행은 자동으로 각 열의 제목이 된다)

         day  temp condition
0     Monday    12     Sunny
1    Tuesday    14      Rain
2  Wednesday    15      Rain
3   Thursday    14    Cloudy
4     Friday    21     Sunny
5   Saturday    22     Sunny
6     Sunday    24     Sunny

DataFrame.to_dict()

data_dict = data.to_dict()                  # 데이터프레임 클래스의 객체를 딕셔너리로 변환
print(data_dict)

{
  'day': {0: 'Monday', 1: 'Tuesday', 2: 'Wednesday', 3: 'Thursday', 4: 'Friday', 5: 'Saturday', 6: 'Sunday'},
  'temp': {0: 12, 1: 14, 2: 15, 3: 14, 4: 21, 5: 22, 6: 24},
  'condition': {0: 'Sunny', 1: 'Rain', 2: 'Rain', 3: 'Cloudy', 4: 'Sunny', 5: 'Sunny', 6: 'Sunny'}
}

DataFrame.to_csv()

data_dict = {                                 # 파이썬으로 딕셔너리 생성
    "students": ["Amy", "Ben", "Carter"],
    "scores": [76, 56, 65]
}
score_data = pd.DataFrame(data_dict)          # 딕셔너리를 판다스 데이터프레임 객체로 변환
score_data.to_csv("new_data.csv")             # 데이터프레임 객체를 CSV 파일로 변환


DataFrame.iterrows()

for (index, row) in score_data.iterrows():   # 위에서 생성한 score_data의 각 행의 (index, row) 튜플 반복 출력
    print(index)
    print(row)
    
for (index, row) in score_data.iterrows(): 
    if row.scores > 60:                      # 조건에 맞는 행의 특정 열만 반복 출력
        print(row.students)

0
students    Amy
scores       76
Name: 0, dtype: object
1
students    Ben
scores       56
Name: 1, dtype: object
2
students    Carter
scores          65
Name: 2, dtype: object


Amy
Carter

DataFrame.merge()

  • 두 개의 데이터프레임을 하나의 특정 열에 병합
    • left dataframeright dataframe으로 분류
    • left.merge(right, ...) 또는 pd.merge(left, right, ...) 으로 작성 가능
  • 파라미터
    • right: 데이터프레임 또는 시리즈
    • on: 두 데이터프레임에 공통으로 존재하는 열 또는 열의 리스트
    • left_on, right_on: 서로 다른 열을 기준으로 병합할 경우 각각 left, right에서 기준이 되는 열을 지정
    • how: join하는 방식 지정
      • 'inner' : 양쪽에 모두 존재하는 키만 포함, 일치하는 값이 없는 행은 제거(기본값)
      • 'outer' : 양쪽의 모든 행을 포함, 양쪽에서 모두 일치하는 값이 없으면 NaN로 채움
      • 'left' : left의 모든 행을 포함, right에서 일치하는 값이 없으면 NaN로 채움
      • 'right' : right의 모든 행을 포함, left에서 일치하는 값이 없으면 NaN로 채움
      • 'cross' : 양쪽의 모든 가능한 조합을 생성
    • suffixes: 중복된 열 이름을 구별하기 위한 접미사(기본값은 ('_x', '_y'), 각각 left와 right의 중복 열 이름에 붙임)

💡 기본키(primary key)

  • 테이블의 각 행을 고유하게 식별하는 열 또는 열의 조합
  • 중복이 없고, NULL 값을 가질 수 없다.

💡 외래키(foreign key)

  • 한 테이블의 열이 다른 테이블의 기본키를 참조할 때 사용
  • 두 테이블 간의 관계를 형성
Student ID Name Age
1 Amy 23
2 Brown 31
3 Clack 28

Students 데이터프레임

기본키: Student ID(각 학생을 고유하게 식별)

Course ID Course Name Student ID
1324 Science 1
6235 Math 1
9122 Art 2

Courses 데이터프레임

기본키: Course ID(각 강의를 고유하게 식별)
외래키: Student ID(Students 데이터프레임의 기본키를 참조, 각 강의가 어떤 학생과 연결되는지 나타냄)

Column

데이터프레임(전체 표)에서 추출한 단일 은 Pandas의 Series 클래스의 객체가 된다.

print(data["temp"])   # [] 표기법
print(data.temp)      # . 표기법

0    12
1    14
2    15
3    14
4    21
5    22
6    24
Name: temp, dtype: int64

💡 [][[]] 의 차이

  • data[“temp”] : temp 열을 Series 타입으로 반환
  • data[[“temp”]] : temp 열을 DataFrame 타입으로 반환(해당 열 하나만 있는 데이터프레임이 된다)

Series.to_list()

temp_list = data["temp"].to_list()      # temp 열을 리스트로 변환
print(temp_list)

[12, 14, 15, 14, 21, 22, 24]

Row

Pandas의 DataFrame과 Series 클래스로 표의 특정 만 출력할 수 있다.

print(data[data["day"] == "Monday"])    # 데이터프레임과 시리즈로 표의 특정 행 출력

      day  temp condition
0  Monday    12     Sunny
  1. 전체 표에서 검색하는 것이 있는 열 찾기
  2. 열에서 검색하는 것과 같은 값이 있는 행을 체크

monday = data[data.day == "Monday"]         # 월요일에 해당하는 행

monday_condition = monday.condition           # 월요일 행에서 condition 열에 접근
print(monday.condition)                       

monday_temp = monday.temp                     # 월요일 행에서 temp 열에 접근
monday_temp_F = (monday_temp * 9/5) + 32      # 섭씨를 화씨로 변환
print(monday_temp_F)

0    Sunny
Name: condition, dtype: object

0    53.6
Name: temp, dtype: float64

Data Science

데이터 사이언스에 활용할 수 있는 판다스 메소드

DataFrame.loc[]

  • 데이터프레임의 특정 행과 열을 라벨(이름)으로 선택
  • df.loc["행 라벨", "열 라벨"] 으로 표기
    • 행 라벨은 인덱스, 열 라벨(선택사항)은 열 이름 또는 열 이름들의 리스트
    • 선택된 부분만 시리즈 형태로 반환됨(데이터프레임으로 반환하려면 각 행과 열 라벨을 다시 리스트로 감싸기)
  • ⚠️ 파이썬 슬라이싱처럼 인덱스 범위를 지정 가능하나, loc는 시작과 끝 숫자가 모두 포함됨
  • 인덱스 대신 특정 열의 값(이름, 점수 등)을 기준으로 접근하려면 조건 명시 필요
  • 둘 이상의 조건을 만족하는 행만 출력하려면 비트 연산자 & 사용
    • e.g. new_data = df.loc[ (df.column_a == 0) & (df.column_b != 0) ]
    • 비트 연산자의 우선순위가 비교 연산자보다 먼저이기 때문에, 비교 연산자에 괄호 필요

DataFrame.iloc[]

  • 데이터프레임의 특정 행과 열을 위치(인덱스 번호)로 선택
  • 인덱스 번호는 첫 번째 행, 열부터 0으로 시작
  • df.iloc["행 번호", "열 번호"] 으로 표기
  • ⚠️ loc와 달리 일반 슬라이싱처럼 끝 숫자가 포함되지 않음

DataFrame.shape

  • 데이터프레임의 차원(행, 열 등)의 개수를 나타내는 튜플 반환
  • NumPy에서 ndarray.shape도 가능

DataFrame.empty

  • 해당 데이터프레임이나 시리즈가 비어있다면 True를 반환
  • NaN 값만 있을 경우 비어있지 않은 것으로 간주되기 때문에 .dropna() 뒤에 붙여서 사용

DataFrame.columns

  • 속성만 사용했을 때는 데이터프레임의 모든 열의 이름을 반환
  • 속성에 리스트로 열 이름들을 할당하면 데이터프레임의 열 이름 변경 가능
    • df.columns = ['열1', '열2', ...]
    • 리스트의 길이와 실제 열 개수 일치시키기

DataFrame.rename()

  • 데이터프레임의 열 또는 행의 이름 변경
  • 파라미터
    • axis: 0 또는 axis 대신 'index' 이름 변경, 1 또는 axis 대신'columns' 이름 변경
    • inplace: False(기본값)는 원본 데이터를 유지, True는 정렬 결과를 원본 데이터에 반영

DataFrame.describe()

  • 데이터프레임의 여러 통계(count, ean, std, min, 25%, 50%, 75%, max)를 반환

DataFrame.info()

  • 데이터프레임에 대한 간결한 정보를 반환

DataFrame.head(), DataFrame.tail()

  • 데이터프레임의 상위, 하위 5개 행(기본값)만 출력
  • 파라미터 n에 값을 전달하여 원하는 개수만큼 출력 가능

DataFrame.sample()

  • 파라미터 n에 전달한 개수만큼의 행을 무작위로 골라서 반환

DataFrame.query()

  • 여러 조건을 필터링하여 만족하는 부분 집합 생성
  • .loc[]& 연산자를 사용하는 것과 같다(.query()에서는 연산자 대신 and 키워드).

DataFrame.drop()

  • 데이터프레임에서 특정 열이나 행을 제거
  • 파라미터
    • axis: 0(기본값)은 행 단위, 1은 열 단위
    • inplace: False(기본값)는 원본 데이터를 유지, True는 정렬 결과를 원본 데이터에 반영

DataFrame.duplicated()

  • 중복된 행(이미 모든 요소들의 값이 같은 행이 존재)을 True로 표시하여 반환(원본 데이터프레임을 변경하지 않음)
  • .duplicated()앞에 ~(논리 부정) 연산자를 붙이면 중복되지 않은 고유한 값만 남게 된다.
  • .values.any() 앞에 연결해서 중복값이 있는지 확인할 수 있다(False를 반환해야 하나도 없다는 뜻).
  • 파라미터
    • subset: 중복을 판단할 때 고려할 단일 열 또는 여러 열의 리스트 전달(기본값은 None, 즉 모든 열)
    • keep:
      • 'first': 중복 데이터 중 처음만 남기고 이후의 항목들을 중복(True)으로 표시(기본값)
      • 'last': 중복 데이터 중 마지막만 남기고 이전의 항목들을 중복(True)으로 표시
      • False: 중복 데이터 전부를 중복(True)으로 표시

DataFrame.drop_duplicates()

  • 중복된 항목을 삭제한 새로운 데이터프레임 반환
  • 파라미터
    • subset (중복 항목을 더 정확히 걸러내기 위해 지정해야 할 때도 있음)
    • keep
    • inplace: False(기본값)는 원본 데이터를 유지, True는 정렬 결과를 원본 데이터에 반영

DataFrame.isin()

  • 특정 열의 값이 주어진 값들과 일치하는지 확인(True인 행만 출력)
  • values 파라미터에 리스트, 시리즈, 데이터프레임, 딕셔너리 등으로 전달

DataFrame.isna()

  • NaN(Not a Number)값일 경우 True를 반환
  • NaN 값은 누락된 데이터(빈 셀)나 정크 데이터(숫자 대신 문자열을 포함하는 셀)를 뜻함
  • .values.any() 앞에 연결해서 NaN 값이 있는지 확인할 수 있다(False를 반환해야 하나도 없다는 뜻).

DataFrame.notna()

  • NaN 값일 아닐 경우 True를 반환
  • isna()의 반대

DataFrame.dropna()

  • 필요없는 행(NaN 값이 포함된)을 제거한 새 데이터프레임 생성
  • 새로 생성된 데이터는 변수에 저장해야 한다.

DataFrame.fillna()

  • NaN 값을 원하는 값으로 변경
  • 파라미터
    • value: 원하는 값(e.g. 0)
    • inplace: False(기본값)는 원본 데이터를 유지, True는 정렬 결과를 원본 데이터에 반영

DataFrame.any()

  • 지정된 범위 내의 값들 중 하나라도 조건을 만족한다면 True를, 아니면 False를 반환
  • 다른 함수 뒤에 연결하여 많이 사용됨

DataFrame.insert()

  • 데이터프레임의 지정된 위치에 새 열을 추가
  • 파라미터
    • loc: 열이 삽입될 위치의 인덱스
    • column: 열 이름(라벨)
    • value: 삽입할 열 데이터
    • allow_duplicates: 중복된 열 이름 허용 여부

DataFrame.stack()

  • 데이터프레임의 열을 행(인덱스)으로 변환(Series 타입으로 결과 반환)
  • 파라미터
    • level: 스택을 수행할 레벨 지정(기본값은 마지막 레벨인 -1)
    • dropna: 결측값 제거 여부(기본값은 True)

DataFrame.set_index()

  • 지정한 열 또는 배열을 데이터프레임의 인덱스로 설정
  • 파라미터
    • keys: 단일 열이나 배열 또는 리스트로 여러 개의 열 전달
    • inplace: False(기본값)는 원본 데이터를 유지, True는 정렬 결과를 원본 데이터에 반영

DataFrame.pivot()

  • 주어진 인덱스, 열 값으로 데이터프레임을 새로 재구성
  • 값이 누락된 항목에는 자동으로 NaN 값이 들어간다.
  • 파라미터
    • columns: 열의 범주
    • index: 행의 범주
    • values: 새로운 셀에 들어갈 값의 범주

DataFrame.sort_values()

  • 데이터프레임(또는 시리즈)를 특정 열이나 값을 기준으로 정렬
  • 파라미터
    • by: 정렬 기준이 되는 열 이름 또는 열 이름의 리스트(Series에는 없는 파라미터)
    • axis: 0(기본값)은 행 단위, 1은 열 단위
    • ascending: True(기본값)는 오름차순, False는 내림차순 정렬(여러 개의 by에 리스트로 개별 지정 가능)
    • inplace: False(기본값)는 원본 데이터를 유지, True는 정렬 결과를 원본 데이터에 반영
    • key: 정렬 기준을 원하는 함수로 지정하려는 경우 사용

DataFrame.rolling()

  • 시계열(time-series) 데이터나 순차적인 데이터에서 지정된 윈도우 크기만큼 데이터를 슬라이딩하면서 계산
  • window 파라미터에 윈도우 크기를 전달(e.g. 3은 현재 값과 이전 2개의 값, 즉 3개의 연속된 값이 기준)
  • 뒤에 .mean()을 연결하면 이동 평균(moving average) 생성(차트의 변화를 확인하며 적당한 window 값 찾기)
  • 계산 결과는 변수에 저장하기

DataFrame.resample()

  • 시계열 데이터를 새로운 시간 단위로 재조정
  • DataFrame.last()로 각 단위의 가장 마지막 상태를 가져올 수 있다.

    ⚠️ 2.1 버전부터는 권장되지 않는 메소드로, 직접 마지막 인덱스에 접근하는 방식을 권고중

  • 파라미터
    • rule: 리샘플링할 주기(연별 빈도는 'Y', 월별 빈도는 'M' )
    • on: 리샘플링할 열(datetime 타입이어야 한다.)

DataFrame.diff()

  • “현재 행(열)의 값 - n행(열) 이전 또는 이후의 값”을 계산하여 반환(기본적으로 float 타입으로 반환)
  • 계산 방향에 따라 맨 처음 또는 마지막 행(열)은 비교할 값이 없기 때문에 무조건 NaN가 된다.
    (.fillna(0) 등으로 값 대체하기)
  • datetime 타입일 경우 차이나는 날짜 수 만큼 n days로 표시됨
  • 파라미터
    • periods: n행(열) 앞의 값을 비교하기 위해 int형으로 값 전달(기본값은 1으로, 음수일 경우 뒤의 값 비교)
    • axis: 0(기본값)은 행 단위, 1은 열 단위

DataFrame.shift()

  • 현재 값이 속한 행(열)을 n행(열)만큼 이동
  • 이동 방향에 따라 맨 처음 또는 마지막 행(열)은 더 이동할 곳이 없기 때문에 무조건 NaN가 된다.
  • 파라미터
    • periods: n행(열) 만큼 앞으로 이동하기 위해 int형으로 값 전달(기본값은 1으로, 음수일 경우 뒤로 이동)
    • axis: 0 또는 'index' 기준, 1 또는 'columns' 기준

DataFrame.groupby()

  • 데이터를 특정 기준으로 그룹화
  • 파라미터
    • by: 열 이름 또는 열 이름의 리스트, 함수 등을 전달하여 그룹화 기준 정하기
    • level: 다중 인덱스가 있는 데이터프레임에서 특정 인덱스 레벨을 기준으로 그룹화(by와 다름)
    • as_index: True(기본값)는 그룹화된 열을 새 데이터프레임의 인덱스로 사용, False는 기존 인덱스 유지
    • dropna: : 결측값 계산에서 제외 여부

DataFrame.count()

  • 각 열(행)에서 NaN 값을 제외한 값만 카운트
  • 파라미터 axis에서 0(기본값)은 열별로 세고(행을 따라 계산)하고, 1은 행별로 센다(열을 따라 계산).
  • .groupby() 메소드의 뒤에 연결하면 특정 그룹의 값만 셀 수 있다.

DataFrame.value_counts()

  • 데이터프레임의 각 행이 나타나는 빈도를 반환

DataFrame.agg()

  • 데이터프레임이나 시리즈에 대해 하나 이상의 집계 함수를 적용 가능
  • 파라미터에 { 키(열 이름): 값(적용할 함수) }처럼 딕셔너리로 전달하면 각 열마다 다른 함수를 적용할 수 있다.
  • .groupby() 메소드의 뒤에 연결하면 특정 데이터프레임 열에 기반한 작업을 할 수 있다.

DataFrame.sum()

  • 총 개수를 계산
  • .isna() 메소드의 뒤에 연결하면 데이터프레임의 열마다 있는 NaN 값의 개수를 셀 수 있다.
  • .groupby() 메소드의 뒤에 연결하면 특정 그룹에 속한 개수를 계산할 수 있다.

DataFrame.cumsum()

  • 누적 합계(cumulative sum)를 계산
  • 첫 번째 값은 그대로 유지되고 그 이후의 값은 이전 값과 현재 값을 누적하여 합산
  • .groupby() 메소드의 뒤에 연결하면 특정 그룹에 대해 누적 합계를 계산할 수 있다.

DataFrame.nlargest(), DataFrame.nsmallest()

  • 데이터프레임에서 가장 큰 값, 가장 작은 값을 가진 행을 반환
  • columns 파라미터의 기준으로 정렬된 상태로 반환된다.
  • 파라미터
    • n: 반환할 행의 개수
    • columns: 기준이 되는 열

Series.mean()

  • 평균값을 계산
  • .groupby() 메소드의 뒤에 연결하면 특정 그룹의 평균값을 계산할 수 있다.

Series.nunique()

  • 특정 열의 고유한 항목의 개수를 반환
  • dropna 파라미터는 기본적으로 NA값을 제외하도록 설정됨
  • 데이터프레임의 행 개수와 nunique의 값이 일치하면 중복되는 항목이나 결측값이 없다는 의미

Series.max(), Series.min()

  • 특정 열에서 가장 큰 값, 가장 작은 값을 반환

Series.idxmax(), Series.idxmin()

  • 특정 열에서 가장 큰 값, 가장 작은 값을 가진 행의 인덱스 반환

Series.add(), Series.sub(), Series.mul(), Series.div()

  • .add() == .addition() → a.add(b)는 a + b
  • .sub() == .subtract() → a.sub(b)는 a - b
  • .mul() == .multiply() → a.mul(b)는 a * b
  • .div()== .divide() → a.div(b)는 a / b
  • 각 연산은 새로운 열 생성

Series.astype()

  • 해당 데이터의 타입을 지정한 타입으로 변경(e.g. str)
  • Series 객체의 .str 속성(문자열일 때만 사용 가능) 앞에 붙여서 문자열로 변환할 때 사용 가능

Series.str

  • 문자열 형식의 데이터를 조작
  • .replace()
    • 해당 열의 값에 있는 특정 문자를 다른 문자로 대체
    • 공백으로 대체할 경우 제거할 수 있다.
  • .split()
    • 해당 열의 값을 특정 문자를 기반으로 해서 분할
    • 파라미터
      • pat: 기준이 될 문자(기본값은 공백)
      • expand: False(기본값)는 리스트/시리즈 반환, True는 분리된 항목을 데이터프레임의 각 열로 반환

Series.dt

  • datetime 형식의 데이터를 조작
  • 속성
    • .year: 연도 추출
    • .month: 월 추출
    • .day: 일 추출
    • .hour: 시간 추출
    • .minute: 분 추출
    • .second: 초 추출
    • .weekday: 요일 추출(월요일을 0으로 반환)


General Functions

.to_datetime()

  • 문자열 등의 데이터 타입을 타임스탬프로 변환
  • 해당 값에는 년(4자리), 월, 일, 시간 등의 정보가 있어야 한다.
  • 변환 후 원래 값에 덮어씌워야 적용됨

.to_numeric()

  • 데이터를 숫자(int, float)로 변환
  • 숫자, 문자, 결측치가 혼합된 데이터에서 유연하게 사용 가능
  • 파라미터
    • expand: False(기본값)는 리스트/시리즈 반환, True는 분리된 항목을 데이터프레임의 각 열로 반환
    • errors:
      • 'raise': 변환할 수 없는 값이 있으면 오류 발생(기본값)
      • 'coerce: 변환 불가능한 값은 NaN으로 처리
      • 'ignore': 변환 불가능한 값은 원래 값 유지

Index Objects

.DatetimeIndex()

  • datetime 객체의 배열로 구성된 Pandas의 인덱스 객체
  • 파라미터에 날짜값으로 이루어진 열을 전달 가능
  • 속성
    • .year: 연도 반환
    • .month: 월 반환
    • .day: 일 반환
    • .weekday: 요일 반환(0은 월요일, 6은 일요일)

Options

import pandas as pd

pd.options.display.float_format = "{:,.2f}".format  # 천 단위 구분기호를 추가하고 소수점 이하 2자리로 고정
  • Pandas의 전역 설정에 영향을 미치는 옵션 수정
  • 원본 데이터에는 영향을 끼치지 않고 파이썬에서 출력되는 형식만 변경됨



References
  1. Angela Yu, [Python 부트캠프 : 100개의 프로젝트로 Python 개발 완전 정복], Udemy, https://www.udemy.com/course/best-100-days-python/?couponCode=ST3MT72524
  2. [API reference], https://pandas.pydata.org/docs/reference/index.html#

Leave a comment