Pandas

yyj·2022년 4월 9일
0

.

목록 보기
20/21

판다스는 내부적으로 2개의 자료구조를 가진다.

Numpy는 ndarry를 판다스는 2개를 가진다.

  • series : 1차원 자료구조, 같은 data type만 저장 가능

  • DataFrame : 2차원 자료구조 series의 집합

  • 시리즈의 집합이 데이터 프레임이다!


Pandas는 외부 module이기 때문에 설치를해서 사용해야 한다

conda install pandas


Series

  • [ ]리스트 형식으로 값을 넣어 줄 수 있지만 같은 type의 값만 넣어 줄 수 있다
    • numpy와 같은 원리
    • index를 설정 할 수 있다!
  • 예제를 통해 알아보자
import numpy as np
import pandas as pd

# ndarray를 생성해보자
arr = np.array([1,2,3,4,5], dtype = np.float64)
print(arr)           # [1. 2. 3. 4. 5.]
# series를 설정해 보자
s = pd.Series([1,2,3,4,5], dtype=np.float64)
print(s)
print(s.values)      # [1. 2. 3. 4. 5.]  ndarray로
print(s.index)       # RangeIndex(start=0, stop=5, step=1) => pands의 객체
print(s.dtype)       # float64

# 시리즈는 1차원 ndarray에 값을 가져와 인덱스와 함께 출력해줌
  • Pandas Series의 인덱스를 따로 잡는 방법
# 인덱스를 따로 잡는 방법
import numpy as np
import pandas as pd

s = pd.Series([1, 2, 3, 4, 5],
                dtype=np.float64,
                index = ['c', 'b', 'a', 'kk', '홍길동' ])
# print(s)
# c      1.0
# b      2.0
# a      3.0
# kk     4.0
# 홍길동    5.0
# dtype: float64

# 만약 인덱스를 지정해서 Series를 만들면 숫자 index는 어떻게 되나?
# 숫자 index는 그대로 사용가능, 내부에 숨어있어요!

print(s[0])           #  숫자 index를 활용하여 1.0 출력
print(s['c'])         # 지정 indx  1.0
# # print(s[100])         # Error 100번째 칸이 없어요!

  • 지정 index를 숫자로 사용하면 어떻게 되나
import numpy as np
import pandas as pd

s = pd.Series([1, 2, 3, 4, 5],
               dtype=np.float64,
               index = [0, 2, 100, 6, 9])
print(s)
# 0      1.0
# 2      2.0
# 100    3.0
# 6      4.0
# 9      5.0
print(s[0])     # 1.0
# print(s[1])     # Error
print(s[100])   # 3.0

# 지정 index가 숫자로 되어있으면 기존에 있던 숫자 인덱스는 사용 못한다1

  • 지정 index에 같은 index가 전해면 어떻게 되나요? 가능!!!!!
import numpy as np
import pandas as pd

s = pd.Series([1, 2, 3, 4, 5],
               dtype=np.float64,
               index = ['c', 'b', 'c', 'k', 'm'])
print(s)
# c    1.0
# b    2.0
# c    3.0
# k    4.0
# m    5.0
print(s['c'])
# 같은인덱스로 되어있는것을 indexing하면 여러개를 가져옴 결국 시리즈형태로 값이 떨어짐
# c    1.0
# c    3.0
# dtype: float64
  • Pandas의 indexing, slicing
# indexing, slicing
# indexin은 ndarray나 list와 비슷!
# 단, slicing은 약간 주의해야해요!

import numpy as np
import pandas as pd

s = pd.Series([1, 2, 3, 4, 5],
               dtype=np.float64,
               index = ['c', 'b', 'a', 'k', 'm'])
print(s)
# c    1.0
# b    2.0
# a    3.0
# k    4.0
# m    5.0
# dtype: float64
print(s[0:3])    # 숫자 index를 이용한 slicing(ndarray와 list와 동일)
# c    1.0
# b    2.0
# a    3.0
# dtype: float64
print(s['c':'a'])  # 지정 index를 사용할때는 앞에도 포함 뒤에도 포함이기 때문에 포함할 위치를 slicing해줘야함
# c    1.0
# b    2.0
# a    3.0
# dtype: float64
  • Pandas의 boolean indexing fancy indexing
# boolean indexing, fancy indexing 역시 적용이 가능
import numpy as np
import pandas as pd

s = pd.Series([1, 2, 3, 4, 5],
               dtype=np.float64,
               index = ['c', 'b', 'a', 'k', 'm'])
print(s)
# c    1.0
# b    2.0
# a    3.0
# k    4.0
# m    5.0
# dtype: float64

# 짝수만 뽑아내는 boolean indexing
print(s[s%2==0])
# b    2.0
# k    4.0
# dtype: float64


# fancy indexing
print(s[[0,2]])
# c    1.0
# a    3.0
# dtype: float64

Series를 만드는 또다른 방법에 대해서도 알아보자!

# index를 key로 저장하는 값을 value로 구성되는 자료구조
# s = pd.Series([1, 2, 3, 4, 5],
#                dtype=np.float64,
#                index = ['c', 'b', 'a', 'k', 'm'])

# dictionary를 이용해서 Series를 생성
my_dict = {'서울': 1000,
           '인천': 500,
           '제주': 200}

s = pd.Series(my_dict)
print(s)
결과
서울    1000
인천     500
제주     200
dtype: int64


예제 문제

  • 예제문제 풀이를 통해 pandas에 대해 좀 더 이해해 보도록 하자
  • 문제 1
### A공장의 2020년 1월 1일부터 10일간 생산량의 Series로 저장

# 생산량의 평균이 50이고 표준편차가 5인 정규분포에서 랜덤하게 생성(정수)

### B공장의 2020년 1월 1일부터 10일간 생산량의 Series로 저장

# 생산량의 평균이 70이고 표준편차가 8인 정규분포에서 랜덤하게 생성(정수)

# index가 날짜

import numpy as np
import pandas as pd
from datetime import datetime, timedelta
# 날짜에 대한 간격을 표현 timedelta

start_day = datetime(2020,1,1)
print(start_day)    # 2020-01-01 00:00:00

# list comprehension => list 생성시 제어문을(for, if) 이용하여 값을 넣어줌

s1 = pd.Series([int(x) for x in np.random.normal(50,5,(10,))],
               index=[start_day + timedelta(days=x) for x in range(10)])
print(s1)
2020-01-01 00:00:00
2020-01-01    52
2020-01-02    53
2020-01-03    52
2020-01-04    59
2020-01-05    51
2020-01-06    45
2020-01-07    52
2020-01-08    41
2020-01-09    54
2020-01-10    46
dtype: int64

s2 = pd.Series([int(x) for x in np.random.normal(70,8,(10,))],
               index=[start_day + timedelta(days=x) for x in range(10)])
print(s2)
2020-01-01    72
2020-01-02    71
2020-01-03    76
2020-01-04    68
2020-01-05    71
2020-01-06    71
2020-01-07    65
2020-01-08    68
2020-01-09    66
2020-01-10    64
dtype: int64

# 날짜별로 생산량의 합을 구하세요!
print(s1+s2)
2020-01-01    124
2020-01-02    124
2020-01-03    128
2020-01-04    127
2020-01-05    122
2020-01-06    116
2020-01-07    117
2020-01-08    109
2020-01-09    120
2020-01-10    110
dtype: int64

  • 문제 2
# 날짜를 다르게해서 생산량의 합을 구해보아요!

### A공장의 2020년 1월 1일부터 10일간 생산량의 Series로 저장

# 생산량의 평균이 50이고 표준편차가 5인 정규분포에서 랜덤하게 생성(정수)

### B공장의 2020년 1월 5일부터 10일간 생산량의 Series로 저장

# 생산량의 평균이 70이고 표준편차가 8인 정규분포에서 랜덤하게 생성(정수)

# index가 날짜

import numpy as np
import pandas as pd
from datetime import datetime, timedelta
# 날짜에 대한 간격을 표현 timedelta

start_day_A_factory = datetime(2020,1,1)
start_day_B_factory = datetime(2020,1,5)


# list comprehension => list 생성시 제어문을(for, if) 이용하여 값을 넣어줌

s1 = pd.Series([int(x) for x in np.random.normal(50,5,(10,))],
               index=[start_day_A_factory + timedelta(days=x) for x in range(10)])
print(s1)
2020-01-01    48
2020-01-02    57
2020-01-03    42
2020-01-04    49
2020-01-05    44
2020-01-06    42
2020-01-07    55
2020-01-08    42
2020-01-09    47
2020-01-10    60
dtype: int64

s2 = pd.Series([int(x) for x in np.random.normal(70,8,(10,))],
               index=[start_day_B_factory + timedelta(days=x) for x in range(10)])
print(s2)
2020-01-05    85
2020-01-06    74
2020-01-07    79
2020-01-08    64
2020-01-09    65
2020-01-10    73
2020-01-11    58
2020-01-12    76
2020-01-13    57
2020-01-14    56
dtype: int64

# 날짜별로 생산량의 합을 구하세요!
print(s1+s2)
2020-01-01      NaN
2020-01-02      NaN
2020-01-03      NaN
2020-01-04      NaN
2020-01-05    129.0
2020-01-06    116.0
2020-01-07    134.0
2020-01-08    106.0
2020-01-09    112.0
2020-01-10    133.0
2020-01-11      NaN
2020-01-12      NaN
2020-01-13      NaN
2020-01-14      NaN
dtype: float64
# 데이터가 일치하지 않는 갑은 NaN으로 출력이 되는 것을 확인 할 수 있다!


Pandas의 DataFrame

  • DataFrame : 2차원 atrix 구소

  • DataFrame은 시리즈의 집합이라 보면된다.

  • 즉, 시리즈를 하나로 세워서 합쳐놓은 2차원 매트릭스 구조!

  • 각각의 컬럼별로는 동일한 데이터를 가지지만 전체적으로는 서로 다른 데이터 타입을 가지고 있을 수 있다!

컬럼컬럼
index데이터데이터
  • 데이터 프레임은 다음과 같은 형식으로 구성 된다.

코드로 표현해보자!

# DataFrame은 dictionary를 이용해서 만들어요!

import numpy as np
import pandas as pd

my_dict = {'이름':['홍길동', '아이유', '김연아', '신사임당'],
           '학년':[4, 3, 2, 1],
           '학점':[1.5, 2.4, 3.9, 3.2]}
# key 값이 컬럼명 데이터 값이 각각의 시리즈로 탁 들어가게 됨
# index는 따로 잡지 않아 숫자 인덱스가 할당이 되는것을 볼 수 있음

df = pd.DataFrame(my_dict)
display(df)
# 	이름	  학년	학점
# 0	홍길동	4	1.5
# 1	아이유	3	2.4
# 2	김연아	2	3.9
# 3	신사임당	1	3.2

# DataFrame의 기본 속성

print(df.shape)  # (4, 3)
# 내부 값들은 2차원 ndarray이기 때문에 값만 뽑아라! 라는 명령을 실행하면 다음과 같이 나온다.
print(df.values)
# [['홍길동' 4 1.5]
#  ['아이유' 3 2.4]
#  ['김연아' 2 3.9]
#  ['신사임당' 1 3.2]]

print(df.size)  # DataFrame안의 요소 개수 12
print(df.ndim)  # 몇차원인가? 2
print(df.index) #  행 index    RangeIndex(start=0, stop=4, step=1)

print(df.columns) # 열 index   index(['이름', '학년', '학점'], dtype='object')

df.index.name = '학번'
df.columns.name = '학생정보'
display(df)
#학생정보 이름  학년	학점
#학번			
# 0	    홍길동	4	1.5
# 1	    아이유	3	2.4
# 2	    김연아	2	3.9
# 3	  신사임당	1	3.2

  • DataFrame의 column명과 index명 변경하기!
import numpy as np
import pandas as pd

my_dict = {'이름':['홍길동', '아이유', '김연아', '신사임당'],
           '학년':[4, 3, 2, 1],
           '학점':[1.5, 2.4, 3.9, 3.2]}

df = pd.DataFrame(my_dict)
display(df)
#	이름	  학년	학점
# 0	홍길동	4	1.5
# 1	아이유	3	2.4
# 2	김연아	2	3.9
# 3	신사임당	1	3.2

# 데이터 프레임의 이름을 바꿔준다. 1. 컬러명  2. index 명
new_df = df.rename(columns={'이름':'학생이름',
                            '학점':'평균평점'},
                    index={0:'one'},
                    inplace=False)

# inplace는 복사본을 만들건지 원본을 수정할건지를 의미
# 옵션값 True면 원본 수정하고 복사본 생성 x
# 옵션값 False면 원본은 냅두고 복사본 생성 o
# 이렇게 rename을 사용하면 컬러명 index명을 변경 할 수 있다!

display(new_df)
#	  학생이름  학년	평균평점
# one	홍길동	4	1.5
# 1	    아이유	3	2.4
# 2	    김연아	2	3.9
# 3	   신사임당	1	3.2

  • DataFrame의 특정 column을 index로 설정하는 방법
# 예를들어서 이름 column을 index로 설정해보아요
# set_index()를 사용하면 된다.

import numpy as np
import pandas as pd

my_dict = {'이름':['홍길동', '아이유', '김연아', '신사임당'],
           '학년':[4, 3, 2, 1],
           '학점':[1.5, 2.4, 3.9, 3.2]}


df = pd.DataFrame(my_dict)
display(df)
#	이름	  학년	학점
# 0	홍길동	4	1.5
# 1	아이유	3	2.4
# 2	김연아	2	3.9
# 3	신사임당	1	3.2

new_df = df.set_index('이름',
                     inplace=False)
display(new_df)
# 	      학년	학점
# 이름		
# 홍길동 	4	1.5
# 아이유	    3	2.4
# 김연아	    2	3.9
# 신사임당	1	3.2
  • 여기 까지가 Data Frame의 기본 사항이다

  • 이제는 여러가지 resource를 이용해서 DataFrame을 생성해보도록 하자!
    ex) csv, MySQL, Database, Open APL 등

  • 예시를 한번 보겠다.

import numpy as np
import pandas as pd
df = pd.read_csv('./data/student.csv')

display(df)
     이름	입학연도	성적
0	아이유	2015	1.5
1	김연아	2016	2.0
2	홍길동	2015	3.1
3	강감찬	2017	1.1
4	이순신	2016	2.7
  • 이런식으로 csv 파일을 불러와 pandas가 가지고 있는 read_csv를 이용하여 해당 파일을 불러 올 수 있다.
profile
초보개발자

0개의 댓글