대화형 파이썬 툴
: Jupyter - Colab
통계 및 수학적 계산을 도와주는 라이브러리
: NumPy
데이터 핸들링 (엑셀 다루기) - 데이터 정제(전처리) (⇒ Garbage in, Garbage out)
: Pandas / SQL / 테블로
엑셀로 데이터 분석 할 수 있는데 왜 파이썬을 배워야 합니까?
(1) 빅데이터 핸들링
⇒ 데이터가 100만행이면 엑셀이 열릴까요? / 컬럼도 갯수가 최소 10개 20개 갑니다.
⇒ 데이터 갯수가 차원이 달진다. / 반복문 ⇒ 10만개씩 10번 반복하면 되지 않을까요?
(2) 자동화
⇒ 파이썬으로 한번 코드로 작성을 해놓으면 → 계속 사용 가능. 반복하지 않아도 됨.
데이터 시각화 ⇒ (1) 설득 (2) 데이터의 숨어있는 패턴 발견
: Matplotlib ⇒ Seaborn ⇒ Plotly
머신러닝 / 딥러닝 → 미래를 예측하기 위해서 활용 & 패턴 찾기
⇒ 어떤 결과를 분석(연구)해서 결과를 내놓았다고 해봅시다.
⇒ 그 다음 사람들의 반응은 뭘까요? ⇒ 잘봤습니다. 그래서 앞으로는 어떻게 되나요? (예측)
파이썬 잘하고, 툴 잘 다루면 분석에 도움을 받을 수 있으나, 그것이 데이터 분석의 본질은 아니다.
그래서 BI(Business Inteligence)-Samsung이 만든 BrighticsAI 툴들을 마주하면 드는 생각이 “이걸 어디서부터 어떻게 접근해야 하는 거지?”하는 생각이 들거다.
⇒ SQL, Crawaling, 개발자에게 요청, 공공데이터 API
⇒ 파이썬 / SQL
garbage in garbage out⇒ storytelling, 포인트: 설득 / 납득
# Colab에서 설치
%pip install numpy
# 라이브러리 import
import numpy as np
nD array: N차원(Dimension) 배열(Array) 객체
np.arange(5)
# array([0, 1, 2, 3, 4])
np.zeros((3,2), dtype='int32')
# array([[0, 0], [0, 0], [0, 0]], dtype=int32)
np.zeros((3,2), dtype='int64')
# array([[0, 0], [0, 0], [0, 0]])
np.ones((3,2), dtype='int32')
# array([[1, 1], [1, 1], [1, 1]], dtype=int32)
np.ones((3,2), dtype='int64')
# array([[1, 1], [1, 1], [1, 1]])
nD array 생성
reshape - 차원과 크기 변경
a = np.arange(6).reshape((3, 2))
a
array([[0, 1],
[2, 3],
[4, 5]])
행렬 내적(=행렬 곱) 계산 (np.dot)
1행1열 ⇒ 1*5 + 2*7 = 19
1행2열 ⇒ 1*6 + 2*8 = 22
2행1열 ⇒ 3*5 + 4*7 = 43
2행1열 ⇒ 3*6 + 4*8 = 50
---
1 2 5 6 19 22
* =
3 4 7 8 43 50
# np.mean() == 평균 계산
arr = np.array([[1,2,3], [4,5,6], [7,8,9]])
arr.shape
# (3, 3)
np.mean((arr), axis=1, dtype="int64")
-> array([2, 5, 8])
=> 각 행의 평균은 2, 5, 8
arr = np.array([1,2,3,4,5,6])
even_indexes = np.arange(0, arr.size, 2)
print(arr[even_indexes])
=> [1 3 5]
------------------------------------------------
arr[even_indexes]
=> array([1, 3, 5])
인덱스는 0부터 시작하기때문에 1, 3, 5 가 맞습니다.
# diag()
arr = np.array([[1,2,3], [4,5,6], [7,8,9]])
arr.shape
# (3, 3)
np.diag(arr)
=> array([1, 5, 9])
# std()
arr = np.array([[1,2,3], [4,5,6], [7,8,9]])
np.std(arr)
# 2.581988897471611
print(arr)
=> [[1 2 3]
[4 5 6]
[7 8 9]]
np.std(arr, axis=0)
=> array([2.44948974, 2.44948974, 2.44948974])
# median()
arr = np.array([1,2,3,4,5])
np.median(arr)
=> 3.0
# Boolean Indexing
arr = np.array([1,4,6,3,9,2,7,8])
arr >= 5 # 5보다 크거나 같으면 True | 5보다 작으면 False
=> array([False, False, True, False, True, False, True, True])
arr[arr >= 5] # 5보다 크거나 같은 값만 출력
=> array([6, 9, 7, 8])
# where()
arr = np.array([1,3,5,2,4,6,3,5,7])
np.where((arr == 3) | (arr == 5))
=> (array([1, 2, 6, 7]),) # 3또는 5인 인덱스는 1,2,6,7번에 위치
# and == &
# or == |
머신러닝에서 많이 사용하는 알고리즘이 있다.
# Colab에서 설치
%pip install pandas
# 라이브러리 import
import pandas as pd
# DF (Data Frame) = Excel : 2개 이상의 Series 데이터
data = {
"country": ["kor", "usa", "china", "japan"],
"rank": [1,2,3,4],
"grade": ["A", "B", "C", "D"]
}
df = pd.DataFrame(data) # csv to json, json to csv, xlsx
df
출력
| index | country | rank | grade |
|---|---|---|---|
| 0 | kor | 1 | A |
| 1 | usa | 2 | B |
| 2 | china | 3 | C |
| 3 | japan | 4 | D |
# 데이터 설랙션 → 데이터를 불러오는 방법
# 1) df.컬럼, df['컬럼']
print(df.country)
print(df.grade)
df[['country','rank']]
> 출력
0 kor
1 usa
2 china
3 japan
Name: country, dtype: object
0 A
1 B
2 C
3 D
Name: grade, dtype: object
| index | country | rank |
|---|---|---|
| 0 | kor | 1 |
| 1 | usa | 2 |
| 2 | china | 3 |
| 3 | japan | 4 |
# 2) df. loc[인덱스값, 컬럼명]
print(df.loc[1])
print(df.loc[:])
print(df.loc[:, 'grade'])
df.loc[:,['grade', 'country']]
# 행 순서가 내가 적은 컬럼 순서대로 출력됨.
> 출력
country usa
rank 2
grade B
Name: 1, dtype: object
country rank grade
0 kor 1 A
1 usa 2 B
2 china 3 C
3 japan 4 D
0 A
1 B
2 C
3 D
Name: grade, dtype: object
| index | grade | country |
|---|---|---|
| 0 | A | kor |
| 1 | B | usa |
| 2 | C | china |
| 3 | D | japan |
조건문도 가능하다.
print(df['rank'] > 2) # boolen indexing 형태로 출력
df[df['rank'] > 2]
# df.loc[df['rank'] > 2] 와 동일
df.loc[df['rank'] > 2, ['grade', 'country']]
# df[df['rank'] > 2][['grade', 'country']] 와 동일
> 출력
0 False
1 False
2 True
3 True
Name: rank, dtype: bool
| index | country | rank | grade |
|---|---|---|---|
| 2 | china | 3 | C |
| 3 | japan | 4 | D |
| index | grade | country |
|---|---|---|
| 2 | C | china |
| 3 | D | japan |
# df.iloc[ ] → location 기반으로 항상 숫자값을 필요로 한다.
ascending=False : 내림차순 정렬df['new_rank'] = [10, 100, 30]
df.sort_values(by='new_rank')
| index | country | grade | rank | new_rank |
|---|---|---|---|---|
| 0 | kor | A | 1 | 10 |
| 2 | china | C | 3 | 30 |
| 1 | usa | B | 2 | 100 |
# null 데이터(NaN) 처리
# 데이터 값 변경
import numpy as np
df.loc[1, 'grade'] = np.nan
df.isnull().sum() # null 데이터 갯수
df.isnull() # boolen indexing
> 출력
country 0
grade 1
rank 0
new_rank 0
dtype: int64
| index | country | grade | rank | new_rank |
|---|---|---|---|---|
| 0 | false | false | false | false |
| 1 | false | true | false | false |
| 2 | false | false | false | false |
inplace = True)# 삭제 (drop)
# 1) 행 데이터 삭제 방법
df.drop([3], inplace=True)
# 2) 컬럼을 삭제
df = df.drop('rank', axis=1)
df['rank'] = [1,2,3]
| index | country | grade | rank |
|---|---|---|---|
| 0 | kor | A | 1 |
| 1 | usa | B | 2 |
| 2 | china | C | 3 |

# Series
data = ['a', 'b', 'c', 'd', 'e']
type(data)
se = pd.Series(data)
type(se)
print(se)
print(se.index)
print(se.values)
print("\n")
# slicing
se[0:3]
# Series 이름, index 이름 생성
se.name = "alphabet"
se.index.name = 'index'
print(se)
> 출력
0 a
1 b
2 c
3 d
4 e
dtype: object
RangeIndex(start=0, stop=5, step=1)
['a' 'b' 'c' 'd' 'e']
index
0 a
1 b
2 c
3 d
4 e
Name: alphabet, dtype: object
# 기술 통계
df.info()
df.describe()
> 출력
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 country 3 non-null object
1 grade 3 non-null object
2 rank 3 non-null int64
dtypes: int64(1), object(2)
memory usage: 200.0+ bytes
| index | rank |
|---|---|
| count | 3.0 |
| mean | 2.0 |
| std | 1.0 |
| min | 1.0 |
| 25% | 1.5 |
| 50% | 2.0 |
| 75% | 2.5 |
| max | 3.0 |
기술통계는 변수의 평균(M)과 표준편차(SD) 그리고 최댓값(MAX)과 최솟값(MIN)을 보고자 할 때 사용하는 분석이다.
주로 논문에서 많이 볼 수 있습니다.
이 기술통계를 엑셀에서 다루는게 쉽지가 않은반면, pandas는 자동으로 계산해준다.

표준편차가 크면, 수치들이 전반적으로 들죽날죽 컸다 작았다 제멋대로구나,
표준편차가 작으면, 수치들이 고만고만 하구나, 하고 이해하시면 됩니다.

정리
Pandas의 목적은 One Sheet를 해결하는 것이다.
아래 영화 데이터를 가지고 연습 문제를 진행해보려고 한다.
영화 데이터
import pandas as pd
json_data = {
"columns": ["Movie", "Release Year", "Audience", "Rating"],
"index": [0, 1, 2, 3, 4, 5, 6, 7],
"data": [
["Avengers", 2012, 1500, 8.8],
["Interstellar", 2014, 1100, 9.1],
["Frozen", 2013, 1020, 8.5],
["About Time", 2013, 950, 8.7],
["The Dark Knight", 2008, 1300, 9.0],
["Inception", 2010, 1200, 8.8],
["La La Land", 2016, 800, 8.6],
["Toy Story", 2010, 980, 8.5]
]
}
# JSON 데이터를 DataFrame으로 변환
df = pd.DataFrame(json_data['data'], columns=json_data['columns'])
df
df.Movie
df["Movie"]
df[["Movie", "Rating"]]
# df[df["Release Year"] > 2013]
# df[df["Release Year"] > 2013][["Movie", "Rating"]]
df.loc[df["Release Year"] > 2013]
# Recommend = (Audience * Rating) // 100
df["Recommend"] = (df["Audience"] * df["Rating"]) //100
df.sort_values(by="Recommend", ascending=False)
df.sort_values(by="Recommend", ascending=False).head(5) # 상위 다섯개
1) 데이터프레임에서 특정 열(컬럼) 삭제하기
df.drop('column_name', axis=1, inplace=True)
2) 데이터프레임에서 결측치(누락값) 있는 행 제거하기
df.dropna(inplace=True)
3) 데이터프레임에서 중복된 행 제거하기
df.drop_duplicates(inplace=True)
4) 데이터프레임에서 특정 조건에 맞는 행 선택하기
df[df['column_name'] == 'value']
5) 데이터프레임에서 특정 열의 값에 따라 그룹화하기
grouped_df = df.groupby('column_name')
6) 그룹화한 데이터프레임에서 특정 통계값 계산하기(예: 평균)
grouped_df.mean()
7) 데이터프레임에서 특정 열의 값에 따라 정렬하기
df.sort_values('column_name', inplace=True)
8) 데이터프레임에서 특정 열의 값에 따라 내림차순으로 정렬하기
df.sort_values('column_name', inplace=True, ascending=False)
9) 데이터프레임에서 특정 열의 값들에 대해 빈도수 구하기
df['column_name'].value_counts()
10) 데이터프레임에서 특정 문자열이 포함된 행 선택하기
df['column_name'].value_counts()
11) 데이터프레임에서 특정 문자열로 시작하는 행 선택하기
df[df['column_name'].str.startswith('text')]
12) 데이터프레임에서 특정 문자열로 끝나는 행 선택하기
df[df['column_name'].str.endswith('text')]
13) 데이터프레임에서 특정 문자열을 다른 문자열로 대체하기
df['column_name'] = df['column_name'].str.replace('old_text', 'new_text')
14) 데이터프레임에서 특정 열에 대해 원-핫 인코딩하기
pd.get_dummies(df['column_name'])
15) 데이터프레임에서 특정 열에 대해 히스토그램 그리기
df['column_name'].hist()
16) 데이터프레임에서 특정 열에 대해 박스 플롯 그리기
df.boxplot(column='column_name')
17) 데이터프레임에서 특정 열에 대해 산점도 그리기
df.plot.scatter(x='column1', y='column2')

실습 예제
# Matplotlib 설치
%pip install matplotlib
# 라이브러리 import
import matplotlib.pyplot as plt
plt.plot([1,2,3,4]) # y값 1,2,3,4 로 증가

import numpy as np
x = np.arange(0,12,1)
y = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y, label="sin", marker="o")
plt.plot(x,y2, label="cos", marker="x")
plt.legend()
# plt.legend(loc=(1,1)) # 범례의 위치 지정
plt.title("sin graph") # 그래프의 제목
plt.xlabel("Time") # 그래프의 x라벨
plt.ylabel("Amplitude") # 그래프의 y라벨
plt.grid() # 그래프 내 그리드(격자) 생성
# limit 값
plt.xlim(0, np.pi)
plt.ylim(-1, 1)

# 위의 사이트에서 가져 온 코드
species = ('Adelie', 'Chinstrap', 'Gentoo')
sex_counts = {
'Male': np.array([73, 34, 61]),
'Female': np.array([73, 34, 58]),
}
width = 0.6 # the width of the bars: can also be len(x) sequence
fig, ax = plt.subplots()
bottom = np.zeros(3)
for sex, sex_count in sex_counts.items():
p = ax.bar(species, sex_count, width, label=sex, bottom=bottom)
bottom += sex_count
ax.bar_label(p, label_type='center')
ax.set_title('Number of penguins by sex')
ax.legend()
plt.show()

한글 폰트 적용 코드
!sudo apt-get install -y fonts-nanum
!sudo fc-cache -fv
!rm ~/.cache/matplotlib -rf
import matplotlib.pyplot as plt
import numpy as np
plt.rc('font', family='NanumBarunGothic')
(1) 개봉 연도별 평점
(2) x축에는 연도 데이터가 들어가야 하고, y축에는 평점 데이터가 들어가면 되겠네요.
data 변경된 부분을 반영하고 싶다면 inplace 필수!!!
생각보다 데이터를 수치화 시키고 시각화 시키는게 재밌었다~