Do it! 쉽게 배우는 파이썬 데이터 분석

05 데이터 분석 기초!




목차

05-1 데이터 파악하기(link)

05-2 변수명 바꾸기(link)

05-3 파생변수 만들기(link)

05-1 데이터 파악하기

데이터를 파악할 때 사용하는 명령어


exam 데이터 파악하기

준비하기

import pandas as pd
exam = pd.read_csv('exam.csv')

head() - 데이터 앞부분 확인하기

exam.head()  # 앞에서부터 5행까지 출력
   id  nclass  math  english  science
0   1       1    50       98       50
1   2       1    60       97       60
2   3       1    45       86       78
3   4       1    30       98       58
4   5       2    25       80       65
exam.head(10)  # 앞에서부터 10행까지 출력
   id  nclass  math  english  science
0   1       1    50       98       50
1   2       1    60       97       60
2   3       1    45       86       78
3   4       1    30       98       58
4   5       2    25       80       65
5   6       2    50       89       98
6   7       2    80       90       45
7   8       2    90       78       25
8   9       3    20       98       15
9  10       3    50       98       45

tail() - 데이터 뒷부분 확인하기

exam.tail()  # 뒤에서부터 5행까지 출력
    id  nclass  math  english  science
15  16       4    58       98       65
16  17       5    65       68       98
17  18       5    80       78       90
18  19       5    89       68       87
19  20       5    78       83       58
exam.tail(10)  # 뒤에서부터 10행까지 출력
    id  nclass  math  english  science
10  11       3    65       65       65
11  12       3    45       85       32
12  13       4    46       98       65
13  14       4    48       87       12
14  15       4    75       56       78
15  16       4    58       98       65
16  17       5    65       68       98
17  18       5    80       78       90
18  19       5    89       68       87
19  20       5    78       83       58

shape - 데이터가 몇 행, 몇 열로 구성되는지 알아보기

exam.shape
(20, 5)

info() - 변수 속성 파악하기

exam.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 5 columns):
 #   Column   Non-Null Count  Dtype
---  ------   --------------  -----
 0   id       20 non-null     int64
 1   nclass   20 non-null     int64
 2   math     20 non-null     int64
 3   english  20 non-null     int64
 4   science  20 non-null     int64
dtypes: int64(5)
memory usage: 928.0 bytes
  • Non-Null Count: 결측치(누락된 값)를 제외하고 구한 값의 개수
  • 변수 속성: int64(정수), float64(실수), object(문자), datetime64(날짜 시간)
  • 64: 64비트
    • 1 비트로 두 개의 값 표현 가능
    • int64: 2^64개의 정수 표현 가능

describe() - 요약 통계량 구하기

exam.describe()
             id     nclass       math    english    science
count  20.00000  20.000000  20.000000  20.000000  20.000000
mean   10.50000   3.000000  57.450000  84.900000  59.450000
std     5.91608   1.450953  20.299015  12.875517  25.292968
min     1.00000   1.000000  20.000000  56.000000  12.000000
25%     5.75000   2.000000  45.750000  78.000000  45.000000
50%    10.50000   3.000000  54.000000  86.500000  62.500000
75%    15.25000   4.000000  75.750000  98.000000  78.000000
max    20.00000   5.000000  90.000000  98.000000  98.000000

mpg 데이터 파악하기

# mpg 데이터 불러오기
mpg = pd.read_csv('mpg.csv')
mpg.head()  # mpg 앞부분 확인
  manufacturer model  displ  year  cyl       trans drv  cty  hwy fl category
0         audi    a4    1.8  1999    4    auto(l5)   f   18   29  p  compact
1         audi    a4    1.8  1999    4  manual(m5)   f   21   29  p  compact
2         audi    a4    2.0  2008    4  manual(m6)   f   20   31  p  compact
3         audi    a4    2.0  2008    4    auto(av)   f   21   30  p  compact
4         audi    a4    2.8  1999    6    auto(l5)   f   16   26  p  compact
mpg.tail()  # mpg 뒷부분 확인
    manufacturer   model  displ  year  cyl  ... drv cty  hwy  fl category
229   volkswagen  passat    2.0  2008    4  ...   f  19   28   p  midsize
230   volkswagen  passat    2.0  2008    4  ...   f  21   29   p  midsize
231   volkswagen  passat    2.8  1999    6  ...   f  16   26   p  midsize
232   volkswagen  passat    2.8  1999    6  ...   f  18   26   p  midsize
233   volkswagen  passat    3.6  2008    6  ...   f  17   26   p  midsize
mpg.shape  #  행, 열 출력
(234, 11)
mpg.info()  #  데이터 속성 확인
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 234 entries, 0 to 233
Data columns (total 11 columns):
 #   Column        Non-Null Count  Dtype  
---  ------        --------------  -----  
 0   manufacturer  234 non-null    object 
 1   model         234 non-null    object 
 2   displ         234 non-null    float64
 3   year          234 non-null    int64  
 4   cyl           234 non-null    int64  
 5   trans         234 non-null    object 
 6   drv           234 non-null    object 
 7   cty           234 non-null    int64  
 8   hwy           234 non-null    int64  
 9   fl            234 non-null    object 
 10  category      234 non-null    object 
dtypes: float64(1), int64(4), object(6)
memory usage: 20.2+ KB
mpg.describe()  #  요약 통계량 출력
            displ         year         cyl         cty         hwy
count  234.000000   234.000000  234.000000  234.000000  234.000000
mean     3.471795  2003.500000    5.888889   16.858974   23.440171
std      1.291959     4.509646    1.611534    4.255946    5.954643
min      1.600000  1999.000000    4.000000    9.000000   12.000000
25%      2.400000  1999.000000    4.000000   14.000000   18.000000
50%      3.300000  2003.500000    6.000000   17.000000   24.000000
75%      4.600000  2008.000000    8.000000   19.000000   27.000000
max      7.000000  2008.000000    8.000000   35.000000   44.000000
mpg.describe(include = 'all')  #  문자 변수 요약 통계량 함께 출력
       manufacturer        model       displ  ...         hwy   fl category
count           234          234  234.000000  ...  234.000000  234      234
unique           15           38         NaN  ...         NaN    5        7
top           dodge  caravan 2wd         NaN  ...         NaN    r      suv
freq             37           11         NaN  ...         NaN  168       62
mean            NaN          NaN    3.471795  ...   23.440171  NaN      NaN
std             NaN          NaN    1.291959  ...    5.954643  NaN      NaN
min             NaN          NaN    1.600000  ...   12.000000  NaN      NaN
25%             NaN          NaN    2.400000  ...   18.000000  NaN      NaN
50%             NaN          NaN    3.300000  ...   24.000000  NaN      NaN
75%             NaN          NaN    4.600000  ...   27.000000  NaN      NaN
max             NaN          NaN    7.000000  ...   44.000000  NaN      NaN

함수와 메서드 차이 알아보기



1. 내장 함수

sum(var)
max(var)


2. 패키지 함수

import pandas as pd
pd.read_csv('exam.csv')
pd.DataFrame({'x' : [1, 2, 3]})


3. 메서드

메서드(method): 변수가 지니고 있는 함수

df.head()
df.info()
변수의 자료 구조에 따라 사용 가능한 메서드가 다르다
# 데이터 프레임
df = pd.read_csv('exam.csv')
df.head()
   id  nclass  math  english  science
0   1       1    50       98       50
1   2       1    60       97       60
2   3       1    45       86       78
3   4       1    30       98       58
4   5       2    25       80       65
# 리스트
var = [1, 2, 3]
var.head()
Error in py_call_impl(callable, dots$args, dots$keywords): AttributeError: 'list' object has no attribute 'head'

어트리뷰트 알아보기

어트리뷰트(attribute): 변수가 지니고 있는 값
# 메서드
df.head()
   id  nclass  math  english  science
0   1       1    50       98       50
1   2       1    60       97       60
2   3       1    45       86       78
3   4       1    30       98       58
4   5       2    25       80       65
# 어트리뷰트
df.shape
(20, 5)
변수의 자료 구조에 따라 지니고 있는 어트리뷰트가 다르다
# 데이터 프레임
df.shape
(20, 5)
# 리스트
var.shape
Error in py_call_impl(callable, dots$args, dots$keywords): AttributeError: 'list' object has no attribute 'shape'

메서드와 어트리뷰트의 차이

05-2 변수명 바꾸기

변수명 바꾸기

1. 데이터 프레임 만들기

df_raw = pd.DataFrame({'var1' : [1, 2, 1],
                       'var2' : [2, 3, 2]})
df_raw
   var1  var2
0     1     2
1     2     3
2     1     2

2. 데이터 프레임 복사본 만들기

  • 오류가 발생하더라도 원 상태로 되돌릴 수 있다
  • 데이터를 비교하면서 변형되는 과정을 검토할 수 있다

df_new = df_raw.copy()  # 복사본 만들기
df_new                  # 출력
   var1  var2
0     1     2
1     2     3
2     1     2

3. 변수명 바꾸기

df_new = df_new.rename(columns = {'var2' : 'v2'})  # var2를 v2로 수정
df_new
   var1  v2
0     1   2
1     2   3
2     1   2

비교하기

df_raw
   var1  var2
0     1     2
1     2     3
2     1     2

데이터 프레임을 복사할 때 df.copy()를 사용하는 이유

  • df_new = df_raw와 같이 작성하면 df_newdf_raw는 이름만 다를 뿐 한 몸처럼
    항상 같은 값 갖게 됨
  • 어느 한쪽 수정하면 다른 한쪽도 수정됨
  • 복사본을 수정해도 원본은 영향받지 않도록 df.copy() 사용

혼자서 해보기

mpg 데이터를 이용해 분석 문제를 해결해 보세요.

mpg 데이터의 변수명은 긴 단어를 짧게 줄인 축약어로 되어 있습니다. cty는 도시 연비,
hwy는 고속도로 연비를 의미합니다. 변수명을 이해하기 쉬운 단어로 바꾸려고 합니다.

Q1. mpg 데이터를 불러와 복사본을 만드세요.

Q2. 복사본 데이터를 이용해 ctycity로, hwyhighway로 수정하세요.

Q3. 데이터 일부를 출력해 변수명이 바뀌었는지 확인해 보세요. 다음과 같은 결과물이 출력
       되어야 합니다.

  manufacturer model  displ  year  cyl  ... drv city  highway  fl category
0         audi    a4    1.8  1999    4  ...   f   18       29   p  compact
1         audi    a4    1.8  1999    4  ...   f   21       29   p  compact
2         audi    a4    2.0  2008    4  ...   f   20       31   p  compact
3         audi    a4    2.0  2008    4  ...   f   21       30   p  compact
4         audi    a4    2.8  1999    6  ...   f   16       26   p  compact

Q1. mpg 데이터를 불러와 복사본을 만드세요.

mpg = pd.read_csv('mpg.csv')  # mpg 데이터 불러오기
mpg_new = mpg.copy()          # 복사본 만들기

Q2. 복사본 데이터를 이용해 ctycity로, hwyhighway로 수정하세요.

mpg_new = mpg_new.rename(columns = {'cty' : 'city'})     # cty를 city로 수정
mpg_new = mpg_new.rename(columns = {'hwy' : 'highway'})  # hwy를 highway로 수정

Q3. 데이터 일부를 출력해 변수명이 바뀌었는지 확인해 보세요. 다음과 같은 결과물이 출력
       되어야 합니다.

mpg_new.head()  # 데이터 일부 출력
  manufacturer model  displ  year  cyl  ... drv city  highway  fl category
0         audi    a4    1.8  1999    4  ...   f   18       29   p  compact
1         audi    a4    1.8  1999    4  ...   f   21       29   p  compact
2         audi    a4    2.0  2008    4  ...   f   20       31   p  compact
3         audi    a4    2.0  2008    4  ...   f   21       30   p  compact
4         audi    a4    2.8  1999    6  ...   f   16       26   p  compact

05-3 파생변수 만들기

파생변수(derived variable)

  • 기존의 변수를 변형해 만든 변수

변수 조합해 파생변수 만들기

df = pd.DataFrame({'var1' : [4, 3, 8],
                   'var2' : [2, 6, 1]})
df
   var1  var2
0     4     2
1     3     6
2     8     1

변수 조합해 파생변수 만들기

df['var_sum'] = df['var1'] + df['var2']         # var_sum 파생변수 만들기
df
   var1  var2  var_sum
0     4     2        6
1     3     6        9
2     8     1        9
df['var_mean'] = (df['var1'] + df['var2']) / 2  # var_mean 파생변수 만들기
df
   var1  var2  var_sum  var_mean
0     4     2        6       3.0
1     3     6        9       4.5
2     8     1        9       4.5

mpg 통합 연비 변수 만들기

mpg['total'] = (mpg['cty'] + mpg['hwy']) / 2  # 통합 연비 변수 만들기
mpg.head()
  manufacturer model  displ  year  cyl  ... cty hwy  fl  category total
0         audi    a4    1.8  1999    4  ...  18  29   p   compact  23.5
1         audi    a4    1.8  1999    4  ...  21  29   p   compact  25.0
2         audi    a4    2.0  2008    4  ...  20  31   p   compact  25.5
3         audi    a4    2.0  2008    4  ...  21  30   p   compact  25.5
4         audi    a4    2.8  1999    6  ...  16  26   p   compact  21.0

파생변수 분석하기

sum(mpg['total']) / len(mpg)  # total 합계를 행 수로 나누기
20.14957264957265
mpg['total'].mean()           # 통합 연비 변수 평균
20.14957264957265

조건문을 활용해 파생변수 만들기

1. 기준값 정하기

mpg['total'].describe()  # 요약 통계량 출력
count    234.000000
mean      20.149573
std        5.050290
min       10.500000
25%       15.500000
50%       20.500000
75%       23.500000
max       39.500000
Name: total, dtype: float64
mpg['total'].plot.hist()  # 그래프 만들기

2. 합격 판정 변수 만들기

import numpy as np

# 20 이상이면 pass, 그렇지 않으면 fail 부여
mpg['test'] = np.where(mpg['total'] >= 20, 'pass', 'fail')
mpg.head()
  manufacturer model  displ  year  cyl  ... hwy fl  category  total  test
0         audi    a4    1.8  1999    4  ...  29  p   compact   23.5  pass
1         audi    a4    1.8  1999    4  ...  29  p   compact   25.0  pass
2         audi    a4    2.0  2008    4  ...  31  p   compact   25.5  pass
3         audi    a4    2.0  2008    4  ...  30  p   compact   25.5  pass
4         audi    a4    2.8  1999    6  ...  26  p   compact   21.0  pass

3. 빈도표로 합격 판정 자동차 수 살펴보기

mpg['test'].value_counts()  # 연비 합격 빈도표 만들기
pass    128
fail    106
Name: test, dtype: int64

4. 막대 그래프로 빈도 표현하기

count_test = mpg['test'].value_counts()  # 연비 합격 빈도표를 변수에 할당
count_test.plot.bar()                    # 연비 합격 빈도 막대 그래프 만들기

축 이름 회전하기
count_test.plot.bar(rot = 0)  # 축 이름 수평으로 만들기

중첩 조건문 활용하기

1. 연비 등급 변수 만들기

# total 기준으로 A, B, C 등급 부여
mpg['grade'] = np.where(mpg['total'] >= 30, 'A',
               np.where(mpg['total'] >= 20, 'B', 'C'))

# 데이터 확인
mpg.head()
  manufacturer model  displ  year  cyl  ... fl category  total  test grade
0         audi    a4    1.8  1999    4  ...  p  compact   23.5  pass     B
1         audi    a4    1.8  1999    4  ...  p  compact   25.0  pass     B
2         audi    a4    2.0  2008    4  ...  p  compact   25.5  pass     B
3         audi    a4    2.0  2008    4  ...  p  compact   25.5  pass     B
4         audi    a4    2.8  1999    6  ...  p  compact   21.0  pass     B

2. 빈도표와 막대 그래프로 연비 등급 살펴보기

count_grade = mpg['grade'].value_counts()  # 등급 빈도표 만들기
count_grade
B    118
C    106
A     10
Name: grade, dtype: int64
count_grade.plot.bar(rot = 0)              # 등급 빈도 막대 그래프 만들기

알파벳순으로 막대 정렬하기

# 등급 빈도표 알파벳순 정렬
count_grade = mpg['grade'].value_counts().sort_index()
count_grade
A     10
B    118
C    106
Name: grade, dtype: int64

count_grade.plot.bar(rot = 0)

메서드 체이닝(method chaining)

  • .을 이용해 메서드를 계속 이어서 작성하는 방법
    • ex: mpg['grade'].value_counts().sort_index()
  • 변수에 여러 메서드를 순서대로 적용
  • 출력 결과를 변수에 할당하고 다시 불러오는 작업 반복하지 않아도 됨
# 출력 결과를 변수에 할당하는 방법
df = mpg['grade']
df = df.value_counts()
df = df.sort_index()

# 메서드 체이닝
df = mpg['grade'].value_counts().sort_index()

필요한 만큼 범주 만들기: ‘범주의 수 - 1’

# A, B, C, D 등급 변수 만들기
mpg['grade2'] = np.where(mpg['total'] >= 30, 'A',
                np.where(mpg['total'] >= 25, 'B',
                np.where(mpg['total'] >= 20, 'C', 'D')))

목록에 해당하는 행으로 변수 만들기

  • |: 버티컬 바(vertical bar)
    • ‘또는(or)’ 을 의미하는 기호
    • [Shift] + [\]로 입력
mpg['size'] = np.where((mpg['category'] == 'compact') |
                       (mpg['category'] == 'subcompact') |
                       (mpg['category'] == '2seater'),
                       'small', 'large')

mpg['size'].value_counts()
large    147
small     87
Name: size, dtype: int64

Warning

np.where()에 여러 조건 입력할 때 각 조건에 괄호 입력 주의

목록에 해당하는 행으로 변수 만들기

df.isin() 사용하기
mpg['size'] = np.where(mpg['category'].isin(['compact', 'subcompact',
'2seater']), 'small', 'large')

mpg['size'].value_counts()
large    147
small     87
Name: size, dtype: int64

정리하기

# 1. 패키지 로드
import pandas as pd
import numpy as np

# 2. 데이터 불러오기
mpg = pd.read_csv('mpg.csv')

# 3. 데이터 파악하기
mpg.head()      # 데이터 앞부분
mpg.tail()      # 데이터 뒷부분
mpg.shape       # 행, 열 수
mpg.info()      # 속성
mpg.describe()  # 요약 통계량

정리하기

# 4. 변수명 바꾸기
mpg = mpg.rename(columns = {'manufacturer' : 'company'})

# 5. 파생변수 만들기
mpg['total'] = (mpg['cty'] + mpg['hwy'])/2                  # 변수 조합
mpg['test'] = np.where(mpg['total'] >= 20, 'pass', 'fail')  # 조건문 활용

# 6. 빈도 확인하기
count_test = mpg['test'].value_counts()  # 빈도표 만들기
count_test.plot.bar(rot = 0)             # 빈도 막대 그래프 만들기

분석 도전

분석 도전

midwest.csv는 미국 동북중부 437개 지역의 인구통계 정보를 담고 있습니다. midwest.csv
이용해 데이터 분석 문제를 해결해 보세요.

문제 1. midwest.csv를 불러와 데이터의 특징을 파악하세요.

문제 2. poptotal(전체 인구) 변수를 total로, popasian(아시아 인구) 변수를 asian으로
            수정하세요.

문제 3. total, asian 변수를 이용해 ‘전체 인구 대비 아시아 인구 백분율’ 파생변수를 추가하고,
            히스토그램을 만들어 분포를 살펴보세요.

문제 4. 아시아 인구 백분율 전체 평균을 구하고, 평균을 초과하면 'large', 그 외에는 'small'
            부여한 파생변수를 만들어 보세요.

문제 5. 'large''small'에 해당하는 지역이 얼마나 많은지 빈도표와 빈도 막대 그래프를
            만들어 확인해 보세요.


midwest 데이터 출처: bit.ly/easypy_52

문제 1. midwest.csv를 불러와 데이터의 특징을 파악하세요.

midwest = pd.read_csv('midwest.csv')  # midwest 데이터 불러오기
midwest.head()                        # 앞부분 출력
midwest.tail()                        # 뒷부분 출력
midwest.shape                         # 행, 열 개수 출력
midwest.info()                        # 변수 속성 출력
midwest.describe()                    # 요약 통계량 출력

문제 2. poptotal(전체 인구) 변수를 total로, popasian(아시아 인구) 변수를 asian으로
            수정하세요.

# poptotal을 total로 수정
midwest = midwest.rename(columns = {'poptotal' : 'total'})

# popasian을 asian으로 수정
midwest = midwest.rename(columns = {'popasian' : 'asian'})

문제 3. total, asian 변수를 이용해 ‘전체 인구 대비 아시아 인구 백분율’ 파생변수를 추가하고,
            히스토그램을 만들어 분포를 살펴보세요.

# 백분율 변수 추가
midwest['ratio'] = midwest['asian'] / midwest['total'] * 100

# 히스토그램 만들기
midwest['ratio'].plot.hist()

문제 4. 아시아 인구 백분율 전체 평균을 구하고, 평균을 초과하면 'large', 그 외에는 'small'
            부여한 파생변수를 만들어 보세요.

# ratio 평균
midwest['ratio'].mean()

# large, small 부여
0.4872461834357345
midwest['group'] = np.where(midwest['ratio'] > 0.4872, 'large', 'small')

문제 5. 'large''small'에 해당하는 지역이 얼마나 많은지 빈도표와 빈도 막대 그래프를
            만들어 확인해 보세요.

# group 빈도 구하기
count_group = midwest['group'].value_counts()
count_group
small    318
large    119
Name: group, dtype: int64

문제 5. 'large''small'에 해당하는 지역이 얼마나 많은지 빈도표와 빈도 막대 그래프를
            만들어 확인해 보세요.

# 막대 그래프 만들기
count_group.plot.bar(rot = 0)