비트교육센터/파이썬

[비트교육센터] 자바 기반 풀스택 개발자 양성 과정(Bigdata) 5일차

달의요정루나 2023. 6. 7. 20:45

1. Pandas

- 데이터 처리와 분석을 위한 라이브러리이다.

- 행과 열로 이루어진 데이터 객체를 만들어 다룰 수 있다.

- 대용량의 데이터들을 처리하는데 매우 편리하다.

 

conda install pandas로 사용하는 가상환경에 pandas를 설치해준다.

1) 코딩문

[1]

import pandas as pd

- 판다스를 선언한다.

s1=pd.Series([10,20,30,40,50])
print(s1)

- 10에서 50까지의 1차원 자료구조를 생성한다.

--> 결과

0    10
1    20
2    30
3    40
4    50
dtype: int64

 

[2]

print(s1.index)
print(s1.values) #numpy 배열타입

- 해당 Series에 대한 인덱스와 값을 출력한다.

- 값을 출력할 때 numpy 배열타입으로 출력한다.

--> 결과

RangeIndex(start=0, stop=5, step=1)
[10 20 30 40 50]

2) 코딩문

[1]

s2=pd.Series(['a','b','c',1,2,3])
print(s2)

- 문자형, 정수형 섞인 복합형 Series를 출력한다.

--> 결과

0    a
1    b
2    c
3    1
4    2
5    3
dtype: object

[2]

n=s2.values
print(n.dtype)

- s2값의 타입을 출력한다.

--> 결과

object

3) 코딩문

[1]

import numpy as np
s3=pd.Series([np.nan,1,2])
print(s3)

- Numpy를 선언하고 NaN을 선언한다.(NaN은 Not a Number의 약어로 표현 불가능한 수치형 결과를 의미한다.)

--> 결과

0    NaN
1    1.0
2    2.0
dtype: float64

4) 코딩문

[1]

index_date=['2023-06-01','2023-06-02','2023-06-03','2023-06-04']
s4=pd.Series([200,187,np.nan,210],index=index_date)
print(s4)

- Series 안에 index를 선언해 인덱스를 직접 지정한다.

- index_date 리스트에는 날짜가 들어간다.

--> 결과

2023-06-01    200.0
2023-06-02    187.0
2023-06-03      NaN
2023-06-04    210.0
dtype: float64

5) 코딩문

[1]

s5=pd.Series({'국어':100,'영어':95, '수학':100})
print(s5)

- Series에 딕셔너리 형태로 Key,value를 집어넣어 출력할 수 있습니다.

--> 결과

국어    100
영어     95
수학    100
dtype: int64

6) 코딩문

[1]

p = pd.date_range(start='2020-01-20', end='2020-01-27')
print(p) #date_range 지원

- 날짜범위 지정을 지원한다.

- 2020년 1월 20일부터 27일 까지의 범위이다.

--> 결과

DatetimeIndex(['2020-01-20', '2020-01-21', '2020-01-22', '2020-01-23',
               '2020-01-24', '2020-01-25', '2020-01-26', '2020-01-27'],
              dtype='datetime64[ns]', freq='D')

[2]

p = pd.date_range(start='2020/01/20', end='2020.01.27')
print(p)

- 날짜에 -가 아닌 /을 이용한다.

--> 결과

DatetimeIndex(['2020-01-20', '2020-01-21', '2020-01-22', '2020-01-23',
               '2020-01-24', '2020-01-25', '2020-01-26', '2020-01-27'],
              dtype='datetime64[ns]', freq='D')

- 그러나 기호가 바뀌어도 정해진 기호가 출력된다.

[3]

p = pd.date_range(start='2023-06-02', periods=7, freq='2D')
print(p)

- periods는 기간의 수를 지정, freq는 일/월/년별을 지정한다(2D는 2일씩).

--> 결과

DatetimeIndex(['2023-06-02', '2023-06-04', '2023-06-06', '2023-06-08',
               '2023-06-10', '2023-06-12', '2023-06-14'],
              dtype='datetime64[ns]', freq='2D')

[4]

p = pd.date_range(start='2023-06-02', periods=5, freq='W')
print(p)

- freq에 W는 주별을 의미한다.(1주일별로)

--> 결과

DatetimeIndex(['2023-06-04', '2023-06-11', '2023-06-18', '2023-06-25',
               '2023-07-02'],
              dtype='datetime64[ns]', freq='W-SUN')

[5]

p = pd.date_range(start='2023-06-02', periods=5, freq='W-MON')
print(p)

- freq: W-MON은 월요일을 기준으로 1주일별로 라는 것을 의미한다.

--> 결과

DatetimeIndex(['2023-06-05', '2023-06-12', '2023-06-19', '2023-06-26',
               '2023-07-03'],
              dtype='datetime64[ns]', freq='W-MON')

[6]

p = pd.date_range(start='2023-01-03', periods=4, freq='QS')
print(p)

- freq: QS는 쿼터시작일을 의미한다.

--> 결과

DatetimeIndex(['2023-04-01', '2023-07-01', '2023-10-01', '2024-01-01'], dtype='datetime64[ns]', freq='QS-JAN')

[7]

p = pd.date_range(start='2023-01-03', periods=4, freq='AS')
print(p)

- freq의 AS는 연도별 시작일을 의미한다.

--> 결과

DatetimeIndex(['2023-06-01 08:00:00', '2023-06-01 09:00:00',
               '2023-06-01 10:00:00', '2023-06-01 11:00:00',
               '2023-06-01 12:00:00', '2023-06-01 13:00:00',
               '2023-06-01 14:00:00', '2023-06-01 15:00:00',
               '2023-06-01 16:00:00', '2023-06-01 17:00:00'],
              dtype='datetime64[ns]', freq='H')

[8]

p = pd.date_range(start='2023-06-01 08:00', periods=10, freq='BH')
print(p)

- freq의 BH는 업무시간 기준주기 09:00~17:00 기준으로 작성한다.

--> 결과

DatetimeIndex(['2023-06-01 09:00:00', '2023-06-01 10:00:00',
               '2023-06-01 11:00:00', '2023-06-01 12:00:00',
               '2023-06-01 13:00:00', '2023-06-01 14:00:00',
               '2023-06-01 15:00:00', '2023-06-01 16:00:00',
               '2023-06-02 09:00:00', '2023-06-02 10:00:00'],
              dtype='datetime64[ns]', freq='BH')

[9]

cbh=pd.offsets.CustomBusinessHour(start='09:00',end='18:00',weekmask='Mon Tue Wed Thu Fri')

- pd.offsets.CustomBusinessHour 함수는 나만의 맞춤형 업무시간을 만드는데 사용된다.

- start: 업무 시작 시간

- end: 업무 시작 종료

- weekmask: 유효한 영업일의 주간 마스크, numpy.busdaycalendar에 전달된다.

p = pd.date_range(start='2023-06-01 08:00', periods=10, freq=cbh)
print(p)

--> 결과

DatetimeIndex(['2023-06-01 09:00:00', '2023-06-01 10:00:00',
               '2023-06-01 11:00:00', '2023-06-01 12:00:00',
               '2023-06-01 13:00:00', '2023-06-01 14:00:00',
               '2023-06-01 15:00:00', '2023-06-01 16:00:00',
               '2023-06-01 17:00:00', '2023-06-02 09:00:00'],
              dtype='datetime64[ns]', freq='CBH')

[10]

p = pd.date_range(start='2020-01-01 10:00', periods=4, freq='30min')
print(p)

- 30분 단위로 4개의 시간을 출력한다.

--> 결과

DatetimeIndex(['2020-01-01 10:00:00', '2020-01-01 10:30:00',
               '2020-01-01 11:00:00', '2020-01-01 11:30:00'],
              dtype='datetime64[ns]', freq='30T')

[11]

p = pd.date_range(start='2020-01-01 10:00', periods=4, freq='10s')
print(p)

- 10초 단위로 4개의 시간을 출력한다.

--> 결과

DatetimeIndex(['2020-01-01 10:00:00', '2020-01-01 10:00:10',
               '2020-01-01 10:00:20', '2020-01-01 10:00:30'],
              dtype='datetime64[ns]', freq='10S')

[12]

index_date=pd.date_range(start='2023-06-01',periods=5, freq='D')
p=pd.Series([51,63,59,48,60],index=index_date)
print(p)

- freq의 D옵션은 달력 날짜 기준 하루 주기이다.(이틀 주기는 2D이다.)

- 하루주기로 5개의 날짜를 출력한다.

--> 결과

2023-06-01    51
2023-06-02    63
2023-06-03    59
2023-06-04    48
2023-06-05    60
Freq: D, dtype: int64

7) 코딩문

[1]

df=pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]])
print(df)

-dataframe은 2차원 데이터구조에 이용되어지고 Row, Column, Series로 구성되어 있다.

--> 결과

   0  1  2
0  1  2  3
1  4  5  6
2  7  8  9

[2]

data=np.array([[1,2,3],[4,5,6],[7,8,9]])
df=pd.DataFrame(data)
print(df)

- 넘파이 배열로 2차원 배열을 만든다.

- 만들어진 배열을 dataframe을 통해서 출력한다.

--> 결과

   0  1  2
0  1  2  3
1  4  5  6
2  7  8  9

[3]

data=np.array([[1,2,3],[4,5,6],[7,8,9]])
index_date=pd.date_range('2023-06-01',periods=3)
columns_list=['A','B','C']
df=pd.DataFrame(data,index=index_date,columns=columns_list)
print(df)

- data: 넘파이 배열로 2차원 배열을 만든다.

- index_date: 6월 1일부터 3일까지의 행 인덱스를 만든다.

- columns_list: A,B,C 열 인덱스를 만든다.

- df: dataframe을 통해서 2차원 데이터프레임을 만든다.

--> 결과

            A  B  C
2023-06-01  1  2  3
2023-06-02  4  5  6
2023-06-03  7  8  9

8) 코딩문

[1]

data = {'연도': [2015, 2016, 2016, 2017, 2017],
        '지사': ['서울', '서울', '부산', '서울', '부산'],
        '고객 수': [200, 250, 150, 300, 200]}
df = pd.DataFrame(data)
print(df)

- data: 딕셔너리 타입으로 연도, 지사, 고객 수를 만든다. 여기서 키는 연도, 지사, 고객수로 컬럼 인덱스가 되고 값은 해당 인덱스에 대한 내용들이다.

--> 결과

     연도  지사  고객 수
0  2015  서울   200
1  2016  서울   250
2  2016  부산   150
3  2017  서울   300
4  2017  부산   200

[2]

data = {'연도': [2015, 2016, 2016, 2017, 2017],
        '지사': ['서울', '서울', '부산', '서울', '부산'],
        '고객 수': [200, 250, 150, 300, 200]}
df = pd.DataFrame(data,columns=['지사','연도','고객 수'])
print(df)

- dataframe에서 columns를 통해서 컬럼 인덱스 위치를 바꿀 수 있다.

--> 결과

   지사    연도  고객 수
0  서울  2015   200
1  서울  2016   250
2  부산  2016   150
3  서울  2017   300
4  부산  2017   200

[3]

print(df.index)
print(df.columns)
print(df.values)

- df.index: RangeIndex는 0부터 시작하는 index가 매겨지는 것이다.

- df.column: 해당 데이터프레임의 컬럼 인덱스를 출력한다.

- df.values: 데이터프레임 컬럼 인덱스에 대한 값을 출력한다.

--> 결과

RangeIndex(start=0, stop=5, step=1)
Index(['지사', '연도', '고객 수'], dtype='object')
[['서울' 2015 200]
 ['서울' 2016 250]
 ['부산' 2016 150]
 ['서울' 2017 300]
 ['부산' 2017 200]]

[4]

df.info()

- 데이터프레임 열 타입, 결측값 개수를 확인하는 메소드이다.

--> 결과

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   지사      5 non-null      object
 1   연도      5 non-null      int64 
 2   고객 수    5 non-null      int64 
dtypes: int64(2), object(1)
memory usage: 248.0+ bytes

9) 코딩문

[1]

s1 = pd.Series([1, 2, 3, 4, 5])
s2 = pd.Series([10, 20, 30, 40, 50])
print(s1 + s2)
print(s2 - s1)
print(s1 * s2)
print(s2 / s1)

--> 결과

0    11
1    22
2    33
3    44
4    55
dtype: int64
0     9
1    18
2    27
3    36
4    45
dtype: int64
0     10
1     40
2     90
3    160
4    250
dtype: int64
0    10.0
1    10.0
2    10.0
3    10.0
4    10.0
dtype: float64

[2]

data1 = {'A': [1, 2, 3, 4, 5],
         'B': [10, 20, 30, 40, 50],
         'C': [100, 200, 300, 400, 500]}
df1 = pd.DataFrame(data1)
print(df1)

data2 = {'A': [6, 7, 8],
         'B': [60, 70, 80],
         'C': [600, 700, 800]}
df2 = pd.DataFrame(data2)
print(df2)
print('='*20)
print(df1 + df2)

- 한쪽 데이터프레임에 행이 적을경우 두 데이터프레임이 더해질때 행이 없는 부분은 NaN으로 처리된다.

--> 결과

   A   B    C
0  1  10  100
1  2  20  200
2  3  30  300
3  4  40  400
4  5  50  500
   A   B    C
0  6  60  600
1  7  70  700
2  8  80  800
====================
      A      B       C
0   7.0   70.0   700.0
1   9.0   90.0   900.0
2  11.0  110.0  1100.0
3   NaN    NaN     NaN
4   NaN    NaN     NaN

10) 코딩문

[1]

table_data3 = {'봄':  [256.5, 264.3, 215.9, 223.2, 312.8],
              '여름': [770.6, 567.5, 599.8, 387.1, 446.2],
              '가을': [363.5, 231.2, 293.1, 247.7, 381.6],
              '겨울': [139.3, 59.9, 76.9, 109.1, 108.1]}
columns_list = ['봄', '여름', '가을', '겨울']
index_list = ['2012', '2013', '2014', '2015', '2016']
df3 = pd.DataFrame(table_data3, columns = columns_list, index = index_list)
print(df3)

--> 결과

          봄     여름     가을     겨울
2012  256.5  770.6  363.5  139.3
2013  264.3  567.5  231.2   59.9
2014  215.9  599.8  293.1   76.9
2015  223.2  387.1  247.7  109.1
2016  312.8  446.2  381.6  108.1

[2]

print(df3.mean()) # 계절별 평균
print('='*30)
print(df3.std())  # 계절별 표준편차
print('='*30)
print(df3.mean(axis=1)) # 연도별 평균
print('='*30)
print(df3.std(axis=1)) # 연도별 표준편차

- axis는 축으로 2차원 배열에서 axis0은 행, axis1은 열을 의미한다.

-> 결과

봄     254.54
여름    554.24
가을    303.42
겨울     98.66
dtype: float64
==============================
봄      38.628267
여름    148.888895
가을     67.358496
겨울     30.925523
dtype: float64
==============================
2012    382.475
2013    280.725
2014    296.425
2015    241.775
2016    312.175
dtype: float64
==============================
2012    274.472128
2013    211.128782
2014    221.150739
2015    114.166760
2016    146.548658
dtype: float64

[3]

print(df.describe())

- 해당 데이터프레임에 대한 요약본을 출력한다.

--> 결과

               연도        고객 수
count     5.00000    5.000000
mean   2016.20000  220.000000
std       0.83666   57.008771
min    2015.00000  150.000000
25%    2016.00000  200.000000
50%    2016.00000  200.000000
75%    2017.00000  250.000000
max    2017.00000  300.000000

11) 코딩문

[1]

KTX_data = {'경부선 KTX': [39060, 39896, 42005, 43621, 41702, 41266, 32427],
            '호남선 KTX': [7313, 6967, 6873, 6626, 8675, 10622, 9228],
            '경전선 KTX': [3627, 4168, 4088, 4424, 4606, 4984, 5570],
            '전라선 KTX': [309, 1771, 1954, 2244, 3146, 3945, 5766],
            '동해선 KTX': [np.nan,np.nan, np.nan, np.nan, 2395, 3786, 6667]}
col_list = ['경부선 KTX','호남선 KTX','경전선 KTX','전라선 KTX','동해선 KTX']
index_list = ['2011', '2012', '2013', '2014', '2015', '2016', '2017']

df_KTX = pd.DataFrame(KTX_data, columns = col_list, index = index_list)
print(df_KTX)

--> 결과

      경부선 KTX  호남선 KTX  경전선 KTX  전라선 KTX  동해선 KTX
2011    39060     7313     3627      309      NaN
2012    39896     6967     4168     1771      NaN
2013    42005     6873     4088     1954      NaN
2014    43621     6626     4424     2244      NaN
2015    41702     8675     4606     3146   2395.0
2016    41266    10622     4984     3945   3786.0
2017    32427     9228     5570     5766   6667.0

[2]

df_KTX.head()

- 가장위에 있는 행 6개를 출력한다.

--> 결과

print(df_KTX.head())#객체타입으로 출력

--> 결과

      경부선 KTX  호남선 KTX  경전선 KTX  전라선 KTX  동해선 KTX
2011    39060     7313     3627      309      NaN
2012    39896     6967     4168     1771      NaN
2013    42005     6873     4088     1954      NaN
2014    43621     6626     4424     2244      NaN
2015    41702     8675     4606     3146   2395.0

[3]

df_KTX.tail()

- 가장 아래쪽 부터 6개의 행을 출력한다.

--> 결과

[4]

df_KTX.head(10)

- 가장 위쪽부터 10개의 행을 출력한다.

--> 결과

[5]

df_KTX[1:2]

- 데이터프레임 인덱스 1번을 출력한다.

--> 결과

[6]

df_KTX[2:5]

- 데이터프레임 인덱스 2에서 4번을 출력한다.

--> 결과

[7]

print(df_KTX.loc['2011'])

- loc: location의 약자로 데이터프레임의 행 또는 칼럼의 label이나 boolean array로 인덱싱하는 방법이다.

- 2011년 행을 인덱싱한다.

--> 결과

경부선 KTX    39060.0
호남선 KTX     7313.0
경전선 KTX     3627.0
전라선 KTX      309.0
동해선 KTX        NaN
Name: 2011, dtype: float64

[8]

df_KTX.loc['2013':'2016']

- 2013년에서 2016년 사이를 인덱싱한다.

--> 결과

[9]

print(df_KTX['경부선 KTX'])

- 컬럼 경부선 KTX를 조회한다.

--> 결과

2011    39060
2012    39896
2013    42005
2014    43621
2015    41702
2016    41266
2017    32427
Name: 경부선 KTX, dtype: int64

[10]

print(df_KTX['경부선 KTX']['2012':'2014'])

- 경부선 KTX 컬럼에서 2012년에서 2014년 인덱스를 조회한다.

--> 결과

2012    39896
2013    42005
2014    43621
Name: 경부선 KTX, dtype: int64

[11]

print(df_KTX['경부선 KTX'][1:4])

- 경부선 KTX 컬럼에서 인덱스 1에서 3의 내용을 조회한다.

--> 결과

2012    39896
2013    42005
2014    43621
Name: 경부선 KTX, dtype: int64

[12]

df_KTX[1:3]

- 인덱스 1에서 2의 열을 출력한다.

--> 결과

[13]

df_KTX[1:3][1:4]

- 기존 표에서 인덱스 1-3이고 그 인덱스 안에서 1-4를 출력한다. 단, 1-3은 이제 0부터 시작된다.

--> 결과

[14]

df_KTX

--> 결과

[15]

df_KTX[1:3][0:2]

--> 결과

[16]

print(df_KTX.loc['2016']['호남선 KTX']) #loc["row"]["col"]
print('='*40)
print(df_KTX.loc['2016','호남선 KTX']) #loc["row","col"]
print('='*40)
print(df_KTX['호남선 KTX']['2016'])
print('='*40)
print(df_KTX['호남선 KTX'][5])
print('='*40)
print(df_KTX['호남선 KTX'].loc['2016']) #loc["col"]

--> 결과

10622.0
========================================
10622
========================================
10622
========================================
10622
========================================
10622

[17]

df_KTX.T #행과 열을 바꿈

--> 결과

[18]

print(df_KTX[['동해선 KTX', '전라선 KTX', '경전선 KTX', '호남선 KTX', '경부선 KTX']])

- 여러가지 컬럼명을 리스트로 선언한 것이다.

--> 결과

      동해선 KTX  전라선 KTX  경전선 KTX  호남선 KTX  경부선 KTX
2011      NaN      309     3627     7313    39060
2012      NaN     1771     4168     6967    39896
2013      NaN     1954     4088     6873    42005
2014      NaN     2244     4424     6626    43621
2015   2395.0     3146     4606     8675    41702
2016   3786.0     3945     4984    10622    41266
2017   6667.0     5766     5570     9228    32427

[19]

df_KTX['호남선 KTX']

- 컬럼 호남선 KTX를 출력한다.

--> 결과

2011     7313
2012     6967
2013     6873
2014     6626
2015     8675
2016    10622
2017     9228
Name: 호남선 KTX, dtype: int64

12) 코딩문

[1]

df1 = pd.DataFrame({'Class1': [95, 92, 98, 100],
                'Class2': [91, 93, 97, 99]})
print(df1)

- 딕셔너리 형으로 선언한다.

- 키 Class1, Class2 에 대한 Value값을 가진 딕셔너리 형 데이터프레임을 선언한다.

--> 결과

   Class1  Class2
0      95      91
1      92      93
2      98      97
3     100      99

 

df2 = pd.DataFrame({'Class1': [87, 89],
                'Class2': [85, 90]})
print(df2)

--> 결과

   Class1  Class2
0      87      85
1      89      90

 

df=pd.concat([df1,df2])
df

- 데이터프레임 df1, df2를 concat으로 결합한다.

- -> 결과

- 하지만 default 값으로 axis=0이 적용되어 행방향으로 데이터프레임을 이어 붙여서 인덱스 값이 위 사진처럼 나왔다.

 

df=pd.concat([df1,df2],ignore_index=True)
df

- 그래서 ignore_index=True를 선언해 인덱스를 재배열해야 한다.

--> 결과

[2]

df=pd.concat([df2,df3],ignore_index=True)
df

- df2와 df3 데이터프레임을 이어 붙이고 ignore_index로 인덱스를 맞추어 준다.

--> 결과

[3]

df4 = pd.DataFrame({'Class3': [93, 91, 95, 98]})
df4

--> 결과

 

df1

--> 결과

 

df=df1.join(df4)
df

- join함수는 매개변수로 들어온 리스트에 있는 요소 하나하나를 합쳐 하나로 바꾸어 반환하는 함수이다.

--> 결과

[4]

index_label = ['a','b','c','d']
df1a = pd.DataFrame({'Class1': [95, 92, 98, 100],
                    'Class2': [91, 93, 97, 99]}, index= index_label)
df4a = pd.DataFrame({'Class3': [93, 91, 95, 98]}, index=index_label)

print(df1a.join(df4a))

--> 결과

   Class1  Class2  Class3
a      95      91      93
b      92      93      91
c      98      97      95
d     100      99      98

[5]

df5 = pd.DataFrame({'Class4': [82, 92]})
df5

--> 결과

 

df1

--> 결과

df1.join(df5)

- join을 하고 만약 결합하려는 칼럼의 인덱스가 적을경우 해당부분은 NaN으로 채워진다.

--> 결과

13) 코딩문

[1]

df_A_B = pd.DataFrame({'판매월': ['1월', '2월', '3월', '4월'],
                       '제품A': [100, 150, 200, 130],
                       '제품B': [90, 110, 140, 170]})
df_A_B

--> 결과

 

 

df_C_D = pd.DataFrame({'판매월': ['1월', '2월', '3월', '4월'],
                       '제품C': [112, 141, 203, 134],
                       '제품D': [90, 110, 140, 170]})
df_C_D

--> 결과

 

df_A_B.merge(df_C_D) #공통된 컬럼은 그대로 둠

--> 결과

 

df_A_B.merge(df_C_D,on='판매월')

- on: 열 기준 병합시 기준으로할 열의 이름이 양측이 동일하다면, on인수에 입력함으로써 기준 열을 정할 수 있습니다.

--> 결과

14) 코딩문

[1]

df_left = pd.DataFrame({'key':['A','B','C'], 'left': [1, 2, 3]})
df_right = pd.DataFrame({'key':['A','B','D'], 'right': [4, 5, 6]})
print(df_left)
print('-'*20)
print(df_right)

--> 결과

  key  left
0   A     1
1   B     2
2   C     3
--------------------
  key  right
0   A      4
1   B      5
2   D      6

[2]

df_left.merge(df_right,how='left',on='key')#왼쪽 기준

- how: 병합시 기준이 될 인덱스를 정하는 방식입니다.

1) left는 기존객체

2) right는 병합할 객체

3) inner은 두 객체의 인덱스의 교집합

4) outer은 두 객체의 인덱스의 합집합

5) cross는 행렬곱

- on: 열 기준 병합시 기준으로할 열의 이름이 양측이 동일하다면, on인수에 입력함으로써 기준 열을 정할 수 있습니다.

--> 결과

[3]

df_left.merge(df_right,how='right',on='key')#오른쪽 기준

--> 결과

[4]

df_left.merge(df_right,how='outer',on='key')

--> 결과

[5]

df_left.merge(df_right,how='inner',on='key')

--> 결과

15) 코딩문

[1]

data = {'연도': [2015, 2016, 2016, 2017, 2017], 
        '지사': ['서울', '서울', '부산', '서울', '부산'],
        '고객 수': [200, 250, 150, 300, 200]}
df = pd.DataFrame(data, columns=['지사','연도', '고객 수'])
print(df)
print('-' * 20)
data = {'연도': [2018], 
    '지사': ['대전'],
        '고객 수': [500]}
row = pd.DataFrame(data, columns=['지사','연도', '고객 수'])
print(row)
print('-' * 20)
df = pd.concat([df, row], ignore_index=True)
print(df)

--> 결과

   지사    연도  고객 수
0  서울  2015   200
1  서울  2016   250
2  부산  2016   150
3  서울  2017   300
4  부산  2017   200
--------------------
   지사    연도  고객 수
0  대전  2018   500
--------------------
   지사    연도  고객 수
0  서울  2015   200
1  서울  2016   250
2  부산  2016   150
3  서울  2017   300
4  부산  2017   200
5  대전  2018   500

[2]

source/python폴더 경로에 data폴더를 만든다.
jupyter lab에서 본 data폴더이다.

[3]

- data폴더 안에 2개의 csv 파일을 넣는다. 하나는 utf-8형식으로 저장 되었고 하나는 euckr이다.

1) UTF-8: 모음 자음으로 나누어져서 조합을 통해 글자가 완성되어 표현된다.

2) EUC-KR: 완성된 단어가 있어야만 표현이 된다.

 

sea_rain1_from_euckr.csv
0.00MB
sea_rain1_from_utf8.csv
0.00MB

[4]

df=pd.read_csv('data/sea_rain1_from_utf8.csv')
df

- read_csv 함수로 sea_rain1_from_utf8.csv를 읽는다.

--> 결과

[5]

df=pd.read_csv('data/sea_rain1_from_euckr.csv',encoding='cp949')
df

- 인코딩: 사람이 사용하는 텍스트를 기계가 이해하는 언어로 표현하는 방법을 말한다.

- cp949: 확장 완성형으로 EUC-KR에 생긴 문제를 해결하기 위해 만들어졌다. cp949로 인코딩 하기 위해서는 반드시 변수 type이 유니코드여야 한다.

- euckr을 그냥 읽을 경우

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbf in position 0: invalid start byte

가 뜨게 된다.

 

--> 결과

16) 코딩문

[1]

df_WH = pd.DataFrame({'Weight':[62, 67, 55, 74],
                      'Height':[165, 177, 160, 180]},
                       index=['ID_1', 'ID_2', 'ID_3', 'ID_4'])
df_WH.index.name = 'User'
df_WH

--> 결과

[2]

bmi = df_WH['Weight']/(df_WH['Height']/100)**2
bmi

- Weight값과 Height값을 통해 bmi를 구한다.

--> 결과

User
ID_1    22.773186
ID_2    21.385936
ID_3    21.484375
ID_4    22.839506
dtype: float64

[3]

df_WH['BMI']=bmi
df_WH

- df_WH데이터프레임에 BMI 컬럼을 추가한다.

- 그리고 계산한 bmi값을 넣어준다.

--> 결과

[4]

df_WH.to_csv('data/bmi.csv')

- df_WH데이터 프레임을 bmi.csv로 data폴더안에 저장한다.

--> 결과

- UTF-8형식으로 저장된 bmi.csv이다.

- to_csv파일로 저장하면 무조건 UTF-8로 저장된다.

 

[5]

df_WH.to_csv('data/bmi.csv',sep=' ',encoding='cp949')

- sep: csv 파일의 구분자 입니다. 기본값은 ' , ' 이다.

- encoding: 인코딩 설정이다. 기본값은 utf-8이다.

--> 결과

 

2. Matplotlib

- 파이썬에서 데이타를 차트나 플롯(Plot)으로 그려주는 라이브러리 패키지로서 가장 많이 사용되는 데이타 시각화(Data Visualization) 패키지로 알려져 있다.

conda install matplotlib로 matplotlib를 설치한다.

1) 코딩문

[1]

import matplotlib.pyplot as plt
data1 = [10,14,19,20,25]
plt.plot(data1)
plt.show()

- matplotlib.pyplot을 import한다.

- plot()함수는 리스트의 값들이 y값들이라고 가정하고 x값을 자동으로 만든다.

- plot()함수에서 data1은 y값이 된다.

--> 결과

[2]

%matplotlib qt
data1 = [10,14,19,20,25]
plt.plot(data1)
plt.show()

- %matplotlib qt는 외부창으로 그래프를 출력한다.

--> 결과

[3]

%matplotlib inline
data1 = [10,14,19,20,25]
plt.plot(data1)
plt.show()

- %matplotlib inline은 브라우저에서 바로 그래프를 볼수 있게 해준다.

--> 결과

2) 코딩문

[1]

import numpy as np
x=np.arange(-4.5,5,0.5)
y=(2*x)**2

- numpy 배열로 -4.5에서 5사이의 값을 0.5 간격으로 x 배열을 만든다.

- y값은 x의 값을 계산해서 들어간다.

x

--> 결과

array([-4.5, -4. , -3.5, -3. , -2.5, -2. , -1.5, -1. , -0.5,  0. ,  0.5,
        1. ,  1.5,  2. ,  2.5,  3. ,  3.5,  4. ,  4.5])
y

-->  결과

array([81., 64., 49., 36., 25., 16.,  9.,  4.,  1.,  0.,  1.,  4.,  9.,
       16., 25., 36., 49., 64., 81.])

 

plt.plot(x,y)
plt.show()

- x축과 y축에 따른 그래프를 출력한다.

--> 결과

[2]

plt.figure(figsize=(4,4))
plt.plot(x,y)
plt.show()

- 그래프 사이즈를 설정시 plt.figure메소드에 figsize옵션을 설정한다.

- figsize(가로길이, 세로길이)

- 단위는 inch이다.

--> 결과

3) 코딩문

[1]

x = np.arange(-4.5, 5, 0.5)
y1 = 2*x**2
y2 = 5*x + 30
y3 = 4*x**2 + 10
plt.plot(x,y1)
plt.plot(x,y2)
plt.plot(x,y3)
plt.show()

- x값에 따른 y값 3종류를 출력한다.

--> 결과

[2]

plt.figure(figsize=(5,4))
plt.figure(figsize=(4,4))
plt.plot(x,y1,x,y2,x,y3)
plt.show()

- figsize 2개가 결합되기 때문에 그래프 출력시

<Figure size 500x400 with 0 Axes>

가 출력된다.

- 그리고 plot에 x와 y값 3개를 집어넣어 3개의 그래프가 들어간 plot을 만들 수 있다.

--> 결과

[3]

plt.plot(x,y1)
plt.figure()
plt.plot(x,y2)
plt.show()

- y1그래프와 y2그래프 2개를 분리시킨다. 

- plt.figure()를 넣어 새로운 figure를 생성한다.

--> 결과

4) 코딩문

[1]

x = np.arange(0, 10, 0.1)
y1 = 0.3*(x-5)**2 + 1
y2 = -1.5*x + 3
y3 = np.sin(x)**2
y4 = 10*np.exp(-x) + 1
plt.subplot(2,2,1)
plt.plot(x,y1)

plt.subplot(2,2,2)
plt.plot(x,y2)

plt.subplot(2,2,3)
plt.plot(x,y3)

plt.subplot(2,2,4)
plt.plot(x,y4)

- subplot()함수는 여러 개의 그래프를 하나의 그림에 나타나게 한다.

- plt.subplot(row, column, index) 함수이다

--> 결과

5) 코딩문

[1]

x=np.linspace(-4,4,100)
y1=x**3
y2=10*x**2-2
plt.plot(x,y1,x,y2)
plt.show()

- np.linspace(): 인자 3개를 기본으로 넣는데 구간 시작점, 구간 끝점, 구간 내 숫자 개수이다. 즉, linspace(-4,4,100)은 -4와 4 사이에 100개의 숫자가 있다는 것이다.

--> 결과

[2]

plt.plot(x,y1,x,y2)
plt.xlim(-1,1)
plt.ylim(-3,3)
plt.show()

- xlim, ylim은 각각 x축과 y축의 범위를 설정한다.

--> 결과

6) 코딩문

[1]

x = np.arange(0, 5, 1)
y1 = x
y2 = x + 1
y3 = x + 2
y4 = x + 3

plt.plot(x, y1, x, y2, x, y3, x, y4)
plt.show()

--> 결과

[2]

plt.plot(x, y1,'m', x, y2,'y', x, y3,'k', x, y4,'c')
plt.show()

- y값 옆에 알파벳을 넣어 그래프 색을 지정할 수 있다.

[3]

plt.plot(x, y1,'-', x, y2,'--', x, y3,':', x, y4,'-.')
plt.show()

- y값 옆에 기호를 넣어 그래프 모양을 바꿀 수 있다.

--> 결과

[4]

plt.plot(x, y1,'o', x, y2,'^', x, y3,'s', x, y4,'d')
plt.show()

- y값 옆에 기호를 넣어 선이 없고 점으로만 된 그래프를 출력할 수 있다.

 

[5]

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4, '-.Xc')
plt.show()

- y값 옆에 알파벳과 기호를 넣어 그래프를 자신이 원하는 대로 커스터마이징할 수 있다.

--> 결과

 

- 그래프 색상 코드 모음사이트

https://matplotlib.org/stable/gallery/color/named_colors.html

 

List of named colors — Matplotlib 3.7.1 documentation

Note Click here to download the full example code List of named colors This plots a list of the named colors supported in matplotlib. For more information on colors in matplotlib see Helper Function for Plotting First we define a helper function for making

matplotlib.org

7) 코딩문

[1]

x=np.arange(-4.5,5,0.5)
y=2*x**3
plt.plot(x,y)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()

- x-label, y-label은 각각 x축과 y축의 이름을 지정해주는 것이다.

--> 결과

[2]

plt.plot(x,y)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Grape Title')
plt.show()

- title은 그래프의 제목을 지어준다.

--> 결과

[3]

plt.plot(x,y)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Grape Title')
plt.grid()
plt.show()

- grid()는 그래프의 격자를 표시해준다.

--> 결과

8) 코딩문

[1]

x=np.arange(0,5,1)
y1=x
y2=x+1
y3=x+2
y4=x+3
plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4, '-.Xc')
plt.legend(['data1','data2','data3','data4'])
plt.show()

- legend는 그래프의 범례를 만들어준다.

--> 결과

[2]

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4, '-.Xc')
plt.legend(['data1','data2','data3','data4'],loc='lower right')
plt.show()

- legend안에 loc를 선언해 범례의 위치를 바꿀 수 있다.

--> 결과

[3]

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4, '-.Xc')
plt.legend(['data1','data2','data3','data4'],loc='lower right')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Grape Title')
plt.grid()
plt.show()

- xlabel, ylabel을 이용해 x축,y축의 이름을 정해준다.

- title은 그래프의 이름을 지정해준다.

- grid는 격자를 만들어준다.

--> 결과

[4]

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4, '-.Xc')
plt.legend(['data1','data2','data3','data4'],loc=1) #loc는 범례위치
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Grape Title')
plt.grid()
plt.show()

- loc에 번호를 넣어 범례위치를 바꿀 수 있다.

--> 결과

9) 코딩문

[1]

x=np.arange(-2,3,1)
y1=x
y2=x+1
y3=x+2
y4=x+3
plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4, '-.Xc')
plt.legend(['data1','data2','data3','data4'])
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Grape Title')
plt.grid()
plt.show()

--> 결과

10) 코딩문

[1]

import platform
from matplotlib import font_manager, rc # Runtime Configuration

path = "c:/Windows/Fonts/malgun.ttf"
if platform.system() == 'Darwin':
    rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc('font', family=font_name)
else:
    print('Unknown system... sorry~~~~')

- 그래프를 출력하다 보면 글꼴이 깨질수 있다 그래서 운영체제 사양에 따라 글꼴을 지정해 주는 코딩문이다.

 

[2]

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4, '-.Xc')
plt.legend(['자료1','자료2','자료3','자료4'])
plt.xlabel('X-축')
plt.ylabel('Y-축')
plt.title('제목')
plt.grid()
plt.show()

--> 결과

 

C:\Users\BIT\miniconda3\envs\p39-env\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 8722 (\N{MINUS SIGN}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

- 그러나 문장이 뜨고 - 기호가 깨진것을 알수 있다.

 

[3]

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4, '-.Xc')
plt.legend(['자료1','자료2','자료3','자료4'])
plt.xlabel('X-축')
plt.ylabel('Y-축')
plt.title('제목')
plt.grid()
plt.xticks(fontname='Arial')
plt.yticks(fontname='Arial')
plt.show()

- 그래서 xticks, yticks를 이용해 x축과 y축의 글꼴을 정해주었다.

--> 결과

11) 코딩문

[1]

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4, '-.Xc')
plt.text(-0.5, -1.5, "문자열 출력 1")
plt.text(-0.5, 0.5, "문자열 출력 2")
plt.text(3, 1, "문자열 출력 3")
plt.text(3, 0, "문자열 출력 4")
plt.xticks(fontname='Arial')
plt.yticks(fontname='Arial')
plt.show()

- text를 통해서 글자를 삽입하고 위치를 지정할 수 있다.

- text함수에서 첫번째는 x위치, 두번째는 y위치, 세번째는 문장을 입력하다.

--> 결과

12) 코딩문

[1]

height = [165, 177, 160, 180, 185, 155, 172]   # 키 데이터
weight = [62, 67, 55, 74, 90, 43, 64]   # 몸무게 데이터
size = 100 * np.arange(1,8)
colors = ['r', 'g', 'b', 'c', 'm', 'k', 'y']
plt.scatter(height,weight,s=size,c=colors)
plt.xlabel('Height(cm) ')
plt.ylabel('Weight(kg) ')
plt.title('키와 몸무게')
plt.grid()
plt.show()

- scatter(x,y,s,c)

1) x: x축 값

2) y: y축 값

3) s: 마커 크기

4) c: 마커 색깔

- 마커크기는 넘파이 범위 1-7에서 100을 곱한 값이다.

--> 결과

13) 코딩문

[1]

city = ['서울', '인천', '대전', '대구', '울산', '부산', '광주']
lat  = [37.56, 37.45, 36.35, 35.87, 35.53, 35.18, 35.16]
lon = [126.97, 126.70, 127.38, 128.60, 129.31, 129.07, 126.85]
pop_den = [16154, 2751, 2839, 2790, 1099, 4454, 2995]
size=np.array(pop_den)*0.2
colors = ['r', 'g', 'b', 'c', 'm', 'k', 'y']
plt.scatter(lon,lat,s=size,c=colors,alpha=0.5)
plt.xlabel('경도')
plt.ylabel('위도')
plt.title('지역별 인구밀도(2017)')

for x,y,name in zip(lon,lat,city):
    plt.text(x,y,name)
plt.show()

- size: 크기는 pop_den 리스트 값에 0.2곱한 것이다.

- scatter의 alpha: 마커의 투명도를 지정한다. 0과 1 사이의 값을 입력한다.

--> 결과

14) 코딩문

[1]

member_IDs = ['m_01', 'm_02', 'm_03', 'm_04'] # 회원 ID
before_ex = [27, 35, 40, 33] # 운동 시작 전
after_ex = [30, 38, 42, 37] # 운동 한 달 후
n_data=len(member_IDs)
index=np.arange(n_data)
plt.bar(index, before_ex)
plt.xticks(fontname='Arial')
plt.yticks(fontname='Arial')
plt.show()

- bar함수는 막대그래프를 만들때 쓰인다.

- bar(x,y): x는 x축에 표시될 회원 ID이고 y는 운동 시작전 값이다.

--> 결과

[2]

plt.bar(index, before_ex, tick_label=member_IDs)
plt.show()

- tick_label은 눈금이름을 의미한다.

--> 결과

[3]

colors=['r','g','b','m']
plt.bar(index, before_ex, tick_label=member_IDs, color=colors)
plt.show()

- color는 그래프 색상을 적용한다.

--> 결과

[4]

colors=['r','g','b','m']
plt.bar(index, before_ex, tick_label=member_IDs, color=colors, width=0.6)
plt.show()

- width는 그래프의 넓이를 담당한다.

--> 결과

[5]

plt.barh(index, before_ex, tick_label=member_IDs, color=colors)
plt.show()

- barh는 수평막대 그래프이다.

- barh(y,x)로 y축에 회원 id, x축은 운동 시작전 값이 적용된다.

- tick_label과 color는 bar()와 같다.

--> 결과

[6]

member_IDs = ['m_01', 'm_02', 'm_03', 'm_04'] # 회원 ID
before_ex = [27, 35, 40, 33] # 운동 시작 전
after_ex = [30, 38, 42, 37] # 운동 한 달 후

n_data=len(member_IDs)
index=np.arange(n_data)

bar_width=0.4
plt.bar(index, before_ex, color='c', width=bar_width, align='edge', label='before')
plt.bar(index+bar_width, after_ex, color='m', align='edge', width=bar_width, label='after')
plt.xticks(index+bar_width,member_IDs)
plt.legend()
plt.xlabel('회원번호')
plt.ylabel('운동수')
plt.title('운동 시작 전/후 비교')
plt.show()

- bar에서 align는 x축 좌표에서 정렬을 수해한다. edge는 막대의 기본 x축 위치에서 왼쪽 모서리로 막대를 이동시킨다.

- label은 범례를 표시한다.

- xticks는 x축에 눈금을 표시한다.

--> 결과

15) 코딩문

[1]

math = [76, 82, 84, 83, 90, 86, 85, 92, 72, 71, 100, 87, 81, 76, 94, 78, 81, 60, 79, 69, 74, 87, 82, 68, 79]
plt.hist(math) #히스토그램
plt.show()

- hist는 히스토그램을 만들어준다. math값에 따라 히스토그램 그래프를 만든다.

- 히스토그램: 도수분포표를 그래프로 나타낸 것으로서, 가로축은 계급, 세로축은 도수 (횟수나 개수 등)를 나타낸다.

--> 결과

[2]

plt.hist(math,bins=8)
plt.show()

- bins는 히스토그램의 가로축 구간의 개수를 지정한다.

--> 결과

[3]

plt.hist(math, bins= 8)
plt.xlabel('시험 점수')
plt.ylabel('도수(frequency)')
plt.title('수학 시험의 히스토그램')
plt.grid()
plt.show()

--> 결과

16) 코딩문

[1]

fruit = ['사과', '바나나', '딸기', '오렌지', '포도']
result = [7, 6, 3, 2, 2]
plt.pie(result)
plt.show()

- result값에 따라 pie함수로 원그래프를 만든다.

--> 결과

[2]

plt.pie(result,labels=fruit,autopct='%.1f')
plt.show()

- labels는 그래프 영역별로 이름을 정해준다.

- autopct는 부채꼴 안에 표시될 숫자의 형식을 지정한다. 소수점 한자리까지 표시할 수 있다.

[3]

plt.pie(result,labels=fruit,autopct='%.1f%%',startangle=90,counterclock=False)
plt.show()

- autopct에서 소수값뒤에 %%를 추가해 퍼센트로 출력한다.

- startangle은 부채꼴이 그려지는 시작 각도를 설정한다. 디폴트는 0도(양의 방향 x축)로 설정되어 있다.

- counterclock=False는 시계 방향 순서로 부채꼴 영역이 표시시켜준다.

--> 결과

[4]

explode_value=[0.1,0,0,0,0]
plt.pie(result,labels=fruit,autopct='%.1f%%',startangle=90,counterclock=False,explode=explode_value,shadow=True)
plt.show()

- explode는 부채꼴이 파이 차트의 중심에서 벗어나는 정도를 설정한다. 여기서는 사과가 10퍼센트 만큼 벗어난다.

- shadow는 파이차트에 그림자가 설정된다.

--> 결과

[5]

plt.pie(result,labels=fruit,autopct='%.1f%%',startangle=90,counterclock=False,explode=explode_value,shadow=True)
plt.savefig('data/fruit.png',dpi=200)
plt.show()

- savefig를 통해서 data폴더에 해당 그래프를 fruit.png로 저장한다. dpi는 선명도를 의미한다.

--> 결과