[NIPA] 데이터 분석 믹스앤 매치 아카데미 - Python - 활용선택 - 파이썬으로 시작하는 데이터 분석(Pandas, Matplotlib)

2020. 11. 28. 05:38통계 & 데이터분석/데이터분석

728x90


1. NumPy

Numpy의 배열은 파이썬의 list()보다도 빠른 연산과 효율적인 메모리 사용이 가능

import numpy as np
#0부터 5사이 랜덤한 값이 담긴 3x5 array를 만들어 봅시다!
import math

array=np.random.randint(0,5,(3,5))

Numpy library에서 자주 사용되는 함수

  • np.array - 배열생성
  • np.zeros - 0이 들어있는 배열 생성
  • np.ones - 1이 들어있는 배열 생성
  • np.empty - 초기화가 없는 값으로 배열을 반환
  • np.arange(n) - 배열 버전의 range 함수
  • np.random.randint - 다양한 난수가 들어있는 배열 생성
import numpy as np

print("1차원 array")
array = np.arange(10)
print(array)
#[0 1 2 3 4 5 6 7 8 9]

print("2차원 array")
matrix = np.arange(1, 16).reshape(3,5)  #1부터 15까지 들어있는 (3,5)짜리 배열을 만듭니다.
print(matrix)

# Q1. array의 자료형을 출력해보세요.
print(type(array))
# <class 'numpy.ndarray'>

# Q2. array의 차원을 출력해보세요.
print(array.ndim)
# 1

# Q3. array의 모양을 출력해보세요.
print(array.shape)
# (10,)

# Q4. array의 크기를 출력해보세요.
print(array.size)
# 10

# Q5. array의 dtype(data type)을 출력해보세요.
print(array.dtype)
# int64

# Q6. array의 인덱스 5의 요소를 출력해보세요.
print(array[5])
# 5

# Q7. array의 인덱스 3의 요소부터 인덱스 5 요소까지 출력해보세요.
print(array[3:6])

  • Reshape() : shape을 변경
  • Concatnate() : 두개 배열을 합쳐 하나의 배열로 만들기
  • Split() : 한개 배열을 두개로 나누기
import numpy as np

# -- Reshape -- #

print("array")
array = np.arange(8)
print(array)
print("shape : ", array.shape, "\n")

#array
#[0 1 2 3 4 5 6 7]
#shape :  (8,) 



# Q1. array를 (2,4) 크기로 reshape하여 matrix에 저장한 뒤 matrix와 그의 shape를 출력해보세요.
print("# reshape (2, 4)")
matrix = array.reshape(2,4)


print(matrix)
print("shape : ", matrix.shape)

# reshape (2, 4)
#[[0 1 2 3]
# [4 5 6 7]]
#shape :  (2, 4)


# -- Concatenate -- #

# Q1. matrix 두 개를 세로로 붙이기 (axis=0)
m=np.concatenate([matrix,matrix],axis=0)
'''
[[0 1 2 3]
 [4 5 6 7]
 [0 1 2 3]
 [4 5 6 7]]
'''

# Q2. matrix 두 개를 가로로 붙이기 (axis=1)
n=np.concatenate([matrix,matrix],axis=1)
'''
[[0 1 2 3 0 1 2 3]
 [4 5 6 7 4 5 6 7]]
'''


# -- Split -- #


# Q1. matrix를 [3] 행에서 axis 0으로 나누기
a, b = np.split(matrix,[3],axis=0)
'''
[[0  1   2  3]
 [4  5   6  7]
 [8  9  10 11]],

 [12 13 14 15]
'''


# Q2. matrix를 [1] 열에서 axis 1로 나누기
c, d = np.split(matrix,[1],axis=1)
'''
[[ 0]
 [ 4]
 [ 8]
 [12]],

[[ 1  2  3]
 [ 5  6  7]
 [ 9 10 11]
 [13 14 15]]
'''

 

  • BroadCasting : Shape이 다른 Array 끼리 연산

import numpy as np

'''
[[0]
 [1]
 [2]
 [3]
 [4]
 [5]] 배열 A와

 [0 1 2 3 4 5] 배열 B를 선언하고, 덧셈 연산해보세요.
'''
A = np.arange(6).reshape(6,1)
B = np.arange(6)
print(A+B)

 

  • 집계 함수 (sum,min,max,mean) 과 Masking 연산
import numpy as np

matrix = np.arange(8).reshape((2, 4))
print(matrix)

# Q1. sum 함수로 matrix의 총 합계를 구해 출력해보세요.
print(np.sum(matrix))

# Q2. max 함수로 matrix 중 최댓값을 구해 출력해보세요.
print(np.max(matrix))

# Q3. min 함수로 matrix 중 최솟값을 구해 출력해보세요.
print(np.min(matrix))

# Q4. mean 함수로 matrix의 평균값을 구해 출력해보세요.
print(np.mean(matrix))

# Q5. sum 함수의 axis 매개변수로 각 열의 합을 구해 출력해보세요.
print(np.sum(matrix, axis=0))

# Q6. sum 함수의 axis 매개변수로 각 행의 합을 구해 출력해보세요.
print(np.sum(matrix, axis=1))

# Q7. std 함수로 matrix의 표준편차를 구해 출력해보세요.
print(np.std(matrix))

# Q8. 마스킹 연산을 이용하여 matrix 중 5보다 작은 수들만 추출하여 출력해보세요.
print(matrix[matrix<5])

2. Pandas 

  • Series : Series 데이터란 Numpy array가 보강된 형태로, Data와 index를 가지고 있는 데이터 형식입니다.
    (1개의 Column)

<< Dictionary → Series >>

import numpy as np
import pandas as pd

# 예시) 시리즈 데이터를 만드는 방법.
series = pd.Series([1,2,3,4], index = ['a', 'b', 'c', 'd'], name="Title")
print(series, "\n")

# 예시) 딕셔너리 -> 시리즈 데이터를 만드는 방법.
population_dict={
'korea' : 5180,
}

country=pd.Series(population_dict)

print(country)

 

<< Seires 연산 >>

A = pd.Series([2, 4, 6], index=[0, 1, 2]) #dtype: int64
B = pd.Series([1, 3, 5], index=[1, 2, 3]) #dtype: int64

A + B
'''
[NaN, 5.0, 9.0, NaN]
dtype : float 64
'''

A.add(B, fill_value=0)
'''
[2.0, 5.0, 9.0, 5.0]
dtype : float 64
'''

 

  • DataFrame : 여러개의 Columns가 있는 Series
# 불러오고 저장하기
country.to_csv("./country.csv")
country.to_excel("./country.xlsx")

country= pd.read_csv("./country.csv")
country= pd.read_excel("./country.xlsx")

# 이곳에서 2개의 시리즈 값이 들어간 데이터프레임을 생성합니다.
print("Country DataFrame")
country = pd.DataFrame({'population':population, 'gdp':gdp})
print(country, '\n')

# 데이터 프레임에 gdp per capita 칼럼을 추가하고 출력합니다.
print("Country gdp per capita")
gdp_per_capita=country['gdp']/country['population']

# -- 방법은 여러가지 -- #
country['gdp per capita']=gdp_per_capita
country.loc['gdp per capita']=[gdp_per_capita]
country.loc['gdp per capita']={gdp_per_capita}
country.loc['gdp per capita']=np.nan


print(country['gdp per capita'], '\n')

# 데이터 프레임을 만들었다면, index와 column도 각각 확인해보세요.
print(country.index)
print(country.columns)

<< DataFrame연산 >>

A = pd.DataFrame(np.random.randint(0, 10, (2, 2)), columns=list("AB"))
B = pd.DataFrame(np.random.randint(0, 10, (3, 3)), columns=list("BAC"))

A + B
'''
[NaN, 5.0, 9.0, NaN]
'''

A.add(B, fill_value=0)
'''
[2.0, 5.0, 9.0, 5.0]
'''

<< 집계 함수 >> : sum,mean 등 동일하게 적용

df= pd.DataFrame(data)
df['A'].sum()
df.sum()
df.mean()

 

  • 명시적 인덱싱(loc) & 정수 인덱싱(iloc)
# 명시적 인덱싱을 사용하여 데이터프레임의 "china" 인덱스를 출력해봅시다.
print(country.loc['china'])

# 정수 인덱싱을 사용하여 데이터프레임의 1번째부터 3번째 인덱스를 출력해봅시다.
print(country.iloc[1:4])

 

  • 정렬(sort)
# 정렬 코드 입력해보기    
# Q1. col1을 기준으로 오름차순으로 정렬하기.
sorted_df1 = df.sort_values('col1', ascending = True)
print(sorted_df1)

# Q2. col2를 기준으로 내림차순으로 정렬하기.
sorted_df2 = df.sort_values('col2', ascending = False)
print(sorted_df2)


# Q3. col2를 기준으로 오름차순으로, col1를 기준으로 내림차순으로 정렬하기.
sorted_df3 = df.sort_values(['col2','col1'] , ascending = [True,False])
print(sorted_df3)

 

  • Pandas 자주 쓰는 함수들
# -- 결측치 -- #
df.isnull()
df.notnull()

df.dropna()
df['__col']=df['__col'].fillna('__value')


# -- 1차원 원소별 함수 적용 -- #
df['__col'].map(function)
@function

# -- 2차원 행/열별 함수 적용 -- #
df.apply(function,axis=0)
# axis = 0 행별
# axis = 1 열별
@function

# -- 2차원 원소별 함수 적용 -- #
df.applymap(function)
@function

 

  • 조건 검색
#데이터 프레임에서 A컬럼값이 0.5보다 작고 B컬럼 값이 0.3보다 큰값들을 구해봅시다.

df[(df['A']<0.5)&(df['B']>0.3)]

df.query("A < 0.5 and B>0.3")

두가지 방법이 있습니다

- 1. df[조건문]

- 2. df.query(조건문)

 

  • 그룹으로 묶기
    - Groupby
    - groupby.get_group(key) : key 값으로 묶인 groupby의 data를 가져 올 수 있습니다
    - Aggregate : groupby를 통한 집계(sum,mean 등등) 을 한번에 계산 할 때
import numpy as np
import pandas as pd

df = pd.DataFrame({
    'key': ['A', 'B', 'C', 'A', 'B', 'C'],
    'data1': [1, 2, 3, 1, 2, 3],
    'data2': [4, 4, 6, 0, 6, 1]
})
'''
DataFrame:
  key  data1  data2
0   A      1      4
1   B      2      4
2   C      3      6
3   A      1      0
4   B      2      6
5   C      3      1 
'''

# -- groupby -- #

# groupby 함수를 이용해봅시다.
# key를 기준으로 묶어 합계를 구해 출력해보세요.
print(df.groupby('key').sum())
'''
     data1  data2
key              
A        2      4
B        4     10
C        6      7
'''

# -- get_group --#
# key 값으로 데이터를 가져 올 수 있습니다
df.groupby('__col').get_group('__value')


# key와 data1을 기준으로 묶어 합계를 구해 출력해보세요.
print(df.groupby(['key','data1']).sum())
'''
           data2
key data1       
A   1          4
B   2         10
C   3          7
'''





# -- aggregate -- #

# aggregate를 이용하여 요약 통계량을 산출해봅시다.
# 데이터 프레임을 'key' 칼럼으로 묶고, data1과 data2 각각의 최솟값, 중앙값, 최댓값을 출력하세요.
print(df.groupby('key').aggregate([min, np.median, max]))
'''
    data1            data2           
      min median max   min median max
key                                  
A       0    1.5   3     0    2.0   4
B       1    2.5   4     4    5.0   6
C       2    3.5   5     1    3.5   6
'''


# 데이터 프레임을 'key' 칼럼으로 묶고, data1의 최솟값, data2의 합계를 출력하세요.
print(df.groupby('key').aggregate({'data1': 'min', 'data2': np.sum}))
'''
     data1  data2
key              
A        0      4
B        1     10
C        2      7
'''




# -- Filter -- #

def filter_by_mean(x):
    return x['data2'].mean() > 3

# groupby()로 묶은 데이터에 filter를 적용해봅시다.
# key별 data2의 평균이 3이 넘는 인덱스만 출력해봅시다.
print("filtering : ")
print(df.groupby('key').filter(filter_by_mean))
'''
filtering : 
  key  data1  data2
1   B      1      4
2   C      2      6
4   B      4      6
5   C      5      1
'''


# groupby()로 묶은 데이터에 apply도 적용해봅시다.
# 람다식을 이용해 최댓값에서 최솟값을 뺀 값을 적용해봅시다.
print("applying : ")
print(df.groupby('key').apply(lambda x: x.max()-x.min()))
'''
applying : 
     data1  data2
key              
A        3      4
B        3      2
C        3      5
'''
'''
DataFrame:
  key  data1  data2
0   A      1      4
1   B      2      4
2   C      3      6
3   A      1      0
4   B      2      6
5   C      3      1 
'''

 

  • 멀티 인덱싱과 Pivot Table
    - 멀티 인덱싱 : 인덱스나 컬럼을 계층적으로 할 수 있다
    - 피벗 테이블 : 필요한 자료만 뽑아서 새롭게 요약
                        * index : 행 인덱스로 들어갈 Key
                        * col : 열 인덱스로 들어갈 라벨링
import numpy as np
import pandas as pd

df1 = pd.DataFrame(
    np.random.randn(4, 2), 
    index=[['A', 'A', 'B', 'B'], [1, 2, 1, 2]],
    columns=['data1', 'data2']
)
'''
DataFrame1
        data1     data2
A 1 -1.247609 -0.226911
  2 -0.454255 -0.092230
B 1 -0.041874 -1.538833
  2  0.200123 -1.487471 
'''


df2 = pd.DataFrame(
    np.random.randn(4, 4),
    columns=[["A", "A", "B", "B"], ["1", "2", "1", "2"]]
)
'''
DataFrame2
          A                   B          
          1         2         1         2
0 -1.179860  1.189611  0.942115  0.794814
1 -1.627063 -0.741212  0.341042  0.473566
2 -0.103281 -0.773662  2.001419  0.893779
3  2.157353 -1.084709  2.085028  1.106763 
'''


# 명시적 인덱싱을 활용한 df1의 인덱스 출력
print("df1.loc['A', 1]")
print(df1.loc['A', 1], "\n") 
'''
df1.loc['A', 1]
data1   -1.247609
data2   -0.226911
Name: (A, 1), dtype: float64 
'''

# df2의 [A][1] 칼럼 출력
print('df2["A"]["1"]')
print(df2["A"]["1"], "\n")
'''
df2["A"]["1"]
0   -1.179860
1   -1.627063
2   -0.103281
3    2.157353
Name: 1, dtype: float64 
'''



# -- Pivot Table -- #
df.pivot_table(
index='sex', columns='class', values='survived',
aggfunc=np.mean
)
'''
class fisrt second third
sex
------------------------
female 0.xx 0.yy   0.zz
male   0.aa 0.bb   0.cc
'''


3. Matplotlib

  • Line Graph
from elice_utils import EliceUtils
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

elice_utils = EliceUtils()

#이미 입력되어 있는 코드의 다양한 속성값들을 변경해 봅시다.
x = np.arange(10)
fig, ax = plt.subplots()
ax.plot(
    x, x, label='y=x',
    marker='o',
    color='blue',
    linestyle=':'
)
ax.plot(
    x, x**2, label='y=x^2',
    marker='^',
    color='red',
    linestyle='--'
)




ax.set_xlabel("x")
ax.set_ylabel("y")
ax.legend(
    loc='upper left',
    shadow=True,
    fancybox=True,
    borderpad=2
)

fig.set_dip(300)
fig.savefig("plot.png")
elice_utils.send_image("plot.png")

 

 

  • Scatter
from elice_utils import EliceUtils
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

elice_utils = EliceUtils()

fig, ax = plt.subplots()
x = np.arange(10)
ax.plot(
    x, x**2, "o",
    markersize=15,
    markerfacecolor='white',
    markeredgecolor="blue"
)

fig.savefig("plot.png")
elice_utils.send_image("plot.png")

 

  • Bar & Histogram
from elice_utils import EliceUtils
elice_utils = EliceUtils()
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
fname='./NanumBarunGothic.ttf'
font = fm.FontProperties(fname = fname).get_name()
plt.rcParams["font.family"] = font


x = np.array(["축구", "야구", "농구", "배드민턴", "탁구"])
y = np.array([18, 7, 12, 10, 8])

z = np.random.randn(1000)


fig, axes = plt.subplots(1, 2, figsize=(8, 4))

# Bar 그래프
axes[0].bar(x, y)
# 히스토그램
axes[1].hist(z, bins = 50)


# elice에서 그래프 확인하기
fig.savefig("plot.png")
elice_utils.send_image("plot.png")

 

 

TIP : 여러개의 plot

fig, axes = plt.subplots(1, 2, figsize=(8, 4))
axes[0].plot(x, np.sin(x))
axes[1].plot(x, np.cos(x))

이 코드는, 하나의 도화지(figure)에 1*2의 모양으로 그래프를 그리도록 합니다.

그래프를 2개 그리고, 가로로 배치한다는 의미입니다. axes[0]은 막대 그래프를, axes[1]은 히스토그램을 그립니다.

 

TIP: 한글폰트 지원

import matplotlib.font_manager as fm
fname='./NanumBarunGothic.ttf'
font = fm.FontProperties(fname = fname).get_name()
plt.rcParams["font.family"] = font

 

  •