아이티윌_데이터 분석 55기/강의내용 필기_Python

#5 5일차_형 변환 함수/매서드, SQL사용, DB 연동, array

ecosso 2026. 5. 15. 15:21

01 형 변환 함수 / 매서드

 -01 함수

 -02 매서드

 

02 파이썬에서의 sql 사용 (SQLite사용)

 

03 DBMS (Oracle) 연동

 -01 필요 라이브러리 설치 및 로딩

 -02 target DB 정보 확인

 -03 접속

 

04 array

 -01 생성

 -02 주요 매서드

 -03 색인

 -04 연산

 -05 축별 연산

 -06 행/열 결합


01 형 변환 함수 / 매서드

 -01 함수
 str, in, float
 상수에만 적용 가능한 함수이다.
 
ex)
str(100)
float(100)
int('100')

str(100)
Out[33]: '100'

float(100)
Out[34]: 100.0

int('100')
Out[35]: 100


str(Series([100,200,300])) # 정상적인 출력이 진행되지 않는다.

 


 -02 매서드
 numpy, pandas에서 제공한다.
 .astype(int)
 
Series([100,200,300]).astype(str)
Series([100,200,300]).astype('float')

Series([100,200,300]).astype(str)
Out[31]: 
0    100
1    200
2    300
dtype: object

Series([100,200,300]).astype('float')
Out[32]: 
0    100.0
1    200.0
2    300.0
dtype: float64

02 파이썬에서의 sql 사용 (SQLite사용)

라이브러리 설치가 필요하며 cmd에서의 실행을 권고한다.

pip install pandasql 을 통해 pandasql 모듈을 설치한다.

 

 ▲ 설치가 완료되었다는 메시지가 출력된다.

 

import pandsql을 통해 모듈을 호출한다.

 

import pandasql
from pandasql import sqldf


ex) emp 테이블에서 10번 부서원의 이름, 급여, 부서번호 출력
import pandas as pd
emp = pd.read_csv('emp.csv')
dept = pd.read_csv('dept.csv')


emp.loc[emp['DEPTNO'] == 10, ['ENAME', 'SAL', 'DEPTNO']]

emp.loc[emp['DEPTNO'] == 10, ['ENAME', 'SAL', 'DEPTNO']]
Out[74]: 
     ENAME   SAL  DEPTNO
6    CLARK  2450      10
8     KING  5000      10
13  MILLER  1300      10

 

sqldf('select ename, sal, deptno from emp where deptno = 10')

sqldf('select ename, sal, deptno from emp where deptno = 10')
Out[76]: 
    ENAME   SAL  DEPTNO
0   CLARK  2450      10
1    KING  5000      10
2  MILLER  1300      10

 

▲ 대소문자를 구분하지 않는다.


 

ex) emp, dept 조인하여 각 직원의 이름, 급여, 부서명 출력
1) oracle 표준
# 오류가 발생한다. 
# 테이블 별칭 선언이 불가능하다.
sqldf('''select e.ename, e.sal, d.dname
       from emp e, dept d
       where e.deptno = d.deptno''')

OperationalError: (sqlite3.OperationalError) no such table: dept
[SQL: select e.ename, e.sal, d.dname
       from emp e, dept d
       where e.deptno = d.deptno]
(Background on this error at: https://sqlalche.me/e/20/e3q8)

During handling of the above exception, another exception occurred:

PandaSQLException                         Traceback (most recent call last)
Cell In[102], line 1
----> 1 sqldf('''select e.ename, e.sal, d.dname
      2        from emp e, dept d
      3        where e.deptno = d.deptno''')

File ~\anaconda3\Lib\site-packages\pandasql\sqldf.py:156, in sqldf(query, env, db_uri)
    124 def sqldf(query, env=None, db_uri='sqlite:///:memory:'):
    125     """
    126     Query pandas data frames using sql syntax
    127     This function is meant for backward compatibility only. New users are encouraged to use the PandaSQL class.
   (...)    154     >>> sqldf("select avg(x) from df;", locals())
    155     """
--> 156     return PandaSQL(db_uri)(query, env)

File ~\anaconda3\Lib\site-packages\pandasql\sqldf.py:63, in PandaSQL.__call__(self, query, env)
     61     result = read_sql(query, conn)
     62 except DatabaseError as ex:
---> 63     raise PandaSQLException(ex)
     64 except ResourceClosedError:
     65     # query returns nothing
     66     result = None

PandaSQLException: (sqlite3.OperationalError) no such table: dept
[SQL: select e.ename, e.sal, d.dname
       from emp e, dept d
       where e.deptno = d.deptno]
(Background on this error at: https://sqlalche.me/e/20/e3q8)


# oracle 표준 조인이 정상적으로 진행되었다.       
sqldf('''select ename, sal, dname
      from emp, dept
      where emp.deptno = dept.deptno''')

sqldf('''select ename, sal, dname
      from emp, dept
      where emp.deptno = dept.deptno''')

Out[103]: 
     ENAME   SAL       DNAME
0    SMITH   800    RESEARCH
1    ALLEN  1600       SALES
2     WARD  1250       SALES
3    JONES  2975    RESEARCH
4   MARTIN  1250       SALES
5    BLAKE  2850       SALES
6    CLARK  2450  ACCOUNTING
7    SCOTT  3000    RESEARCH
8     KING  5000  ACCOUNTING
9   TURNER  1500       SALES
10   ADAMS  1100    RESEARCH
11   JAMES   950       SALES
12    FORD  3000    RESEARCH
13  MILLER  1300  ACCOUNTING

 

2) ansi  표준
# ansi 표준의 경우 테이블 별칭 선언이 가능하다.
sqldf('''select ename, sal, dname
      from emp e
      join dept d
      on e.deptno = d.deptno''')

sqldf('''select ename, sal, dname
      from emp e
      join dept d
      on e.deptno = d.deptno''')
Out[104]: 
     ENAME   SAL       DNAME
0    SMITH   800    RESEARCH
1    ALLEN  1600       SALES
2     WARD  1250       SALES
3    JONES  2975    RESEARCH
4   MARTIN  1250       SALES
5    BLAKE  2850       SALES
6    CLARK  2450  ACCOUNTING
7    SCOTT  3000    RESEARCH
8     KING  5000  ACCOUNTING
9   TURNER  1500       SALES
10   ADAMS  1100    RESEARCH
11   JAMES   950       SALES
12    FORD  3000    RESEARCH
13  MILLER  1300  ACCOUNTING


# ansi 표준 조인이 정상적으로 진행되었다.     
sqldf('''select ename, sal, dname
      from emp
      join dept
      on emp.deptno = dept.deptno''')

sqldf('''select ename, sal, dname
      from emp
      join dept
      on emp.deptno = dept.deptno''')
Out[105]: 
     ENAME   SAL       DNAME
0    SMITH   800    RESEARCH
1    ALLEN  1600       SALES
2     WARD  1250       SALES
3    JONES  2975    RESEARCH
4   MARTIN  1250       SALES
5    BLAKE  2850       SALES
6    CLARK  2450  ACCOUNTING
7    SCOTT  3000    RESEARCH
8     KING  5000  ACCOUNTING
9   TURNER  1500       SALES
10   ADAMS  1100    RESEARCH
11   JAMES   950       SALES
12    FORD  3000    RESEARCH
13  MILLER  1300  ACCOUNTING

 

 ▶ 따라서 별칭 선언을 반드시 해야만하는 상황이라면 ansi 표준을 사용하는 것이 좋다.


 

ex) gogak, gift를 사용하여 모든 고객의 이름과 포인트 기준으로 받을 수 있는 상품명 하나씩을 출력
gogak = pd.read_csv('gogak.csv', encoding = 'cp949')
gift = pd.read_csv('gift.csv', encoding = 'cp949')

gogak.head()
gift.head()

gogak.head()
Out[109]: 
        GNO GNAME          JUMIN   POINT
0  20010001   서진수  7510231369824  980000
1  20010002   서재수  7502241128467   73000
2  20010003   이미경  7506152123648  320000
3  20010004   김재수  7512251063421   65000
4  20010005   박동호  7503031639826  180000

gift.head()
Out[110]: 
   GNO   GNAME  G_START   G_END
0    1    참치세트        1  100000
1    2    샴푸세트   100001  200000
2    3  세차용품세트   200001  300000
3    4  주방용품세트   300001  400000
4    5  산악용자전거   400001  500000

 

sqldf('''select gogak.gname, point, gift.gname
      from gogak, gift
      where gogak.point between gift.g_start and gift.g_end''')

sqldf('''select gogak.gname, point, gift.gname
      from gogak, gift
      where gogak.point between gift.g_start and gift.g_end''')
Out[114]: 
   GNAME   POINT   GNAME
0    서진수  980000  양쪽문냉장고
1    서재수   73000    참치세트
2    이미경  320000  주방용품세트
3    김재수   65000    참치세트
4    박동호  180000    샴푸세트
5    김신영  153000    샴푸세트
6    신은경  273000  세차용품세트
7    오나라  315000  주방용품세트
8    김설희  542000  LCD모니터
9    임세현  265000  세차용품세트
10   최순규  110000    샴푸세트
11   정현영   99000    참치세트
12   안광훈  470000  산악용자전거
13   모병환  298000  세차용품세트
14   노정호  420000  산악용자전거
15   이윤나  598000  LCD모니터
16   안은수  625000     노트북
17   인영민  670000     노트북
18   김지영  770000   벽걸이TV
19    허우  730000   벽걸이TV

 

ex) emp에서 각 직원의 이름, 급여, 입사년도 출력 (단, hiredate는 문자컬럼)
emp = pd.read_csv('emp.csv', parse_dates = ['HIREDATE'])
sqldf('select ename, sal, substr(hiredate, 1, 4) as hyear from emp')

sqldf('select ename, sal, substr(hiredate, 1, 4) as hyear from emp')
Out[131]: 
     ENAME   SAL hyear
0    SMITH   800  1980
1    ALLEN  1600  1981
2     WARD  1250  1982
3    JONES  2975  1981
4   MARTIN  1250  1981
5    BLAKE  2850  1981
6    CLARK  2450  1981
7    SCOTT  3000  1987
8     KING  5000  1981
9   TURNER  1500  1981
10   ADAMS  1100  1987
11   JAMES   950  1981
12    FORD  3000  1981
13  MILLER  1300  1982

 

sqldf("select ename, sal, to_char(hiredate), 'yyyy' as hyer from emp") # SQLite에는 to_char 함수가 없다.

PandaSQLException: (sqlite3.OperationalError) no such function: to_char
[SQL: select ename, sal, to_char(hiredate), 'yyyy' as hyer from emp]
(Background on this error at: https://sqlalche.me/e/20/e3q8)


sqldf("select ename, sal, strftime('%Y', hiredate) as hyer from emp")

sqldf("select ename, sal, strftime('%Y', hiredate) as hyer from emp")
Out[134]: 
     ENAME   SAL  hyer
0    SMITH   800  1980
1    ALLEN  1600  1981
2     WARD  1250  1982
3    JONES  2975  1981
4   MARTIN  1250  1981
5    BLAKE  2850  1981
6    CLARK  2450  1981
7    SCOTT  3000  1987
8     KING  5000  1981
9   TURNER  1500  1981
10   ADAMS  1100  1987
11   JAMES   950  1981
12    FORD  3000  1981
13  MILLER  1300  1982

03 DBMS (Oracle) 연동

Python에서 외부 DBMS(Oracle, SQL Server 등)에 접속해서 데이터를 불러오기 위해 사용한다.

Python에서 만든 객체(데이터프레임)를 DB에 새로운 테이블로 생성이 가능하다. (테이블 생성 권한 필요)

 

 -01 필요 라이브러리 설치 및 로딩

pip install sqlalchemy # cmd에서 실행 권고

 

pip install cx_oracle # 에러발생

 

canda install -c anaconda cx_oracle

 ▲ 기본이 [y]로 되어있다. 엔터를 입력하면 설치가 진행된다.

 

import sqlalchemy
import cx_Oracle

 ▲ 설치할 때는 cs_oracle이었지만 import 시에는 cx_Oracle이다. (대소문자 오타 주의)


 -02 target DB 정보 확인

  1) ip : target DB가 설치된 서버 (PC)의 IP 주소 (python과 같은 위치에 설치된 경우 localhost)

  2) port : target DB의 리스너 port 번호 (기본 : 1521)

  3) SID : target DB 이름 (orci)

  4) userid : 접속할 계정 이름

  5) passwd : 게정 패스워드

 

* 2026.03.08 - [아이티윌_데이터 분석 55기/강의내용 필기_SQL] - #1) 1일차_오라클과 오렌지 설치하기, SELECT문

 

* target DB 정보 확인

cmd > isnrctl stauts (DB가 여러개 설치된 경우 path에서의 실행순서 변경이 필요하다.)


 -03 접속

 +) 생성 권한 및 방화벽에 대한 사항도 검토를 같이 해야한다.

 

from sqlalchemy import create_engine

1) DBMS 접속 정의
create_engine('oracle+cx_oracle://userid:passwd@ip:port/sid')
con1 = create_engine('oracle+cx_oracle://scott:oracle@localhost:1521/orcl')

2) 연동 및 데이터 불러오기
pd.read_sql('select sysdate from dual', con = con1)

pd.read_sql('select sysdate from dual', con = con1)
Out[147]: 
              sysdate
0 2026-05-15 12:04:52

 

pd.read_sql('select ename, dname from emp e, dept d where e.deptno = d.deptno', con = con1)

pd.read_sql('select ename, dname from emp e, dept d where e.deptno = d.deptno', con = con1)
Out[148]: 
     ename       dname
0    SMITH  OPERATIONS
1    ALLEN       SALES
2     WARD       SALES
3    JONES    RESEARCH
4   MARTIN       SALES
5    BLAKE       SALES
6    CLARK  ACCOUNTING
7    SCOTT    RESEARCH
8     KING  ACCOUNTING
9   TURNER       SALES
10   ADAMS    RESEARCH
11   JAMES       SALES
12    FORD    RESEARCH
13  MILLER  ACCOUNTING

 

pd.read_sql("select ename, to_char(hiredate, 'yyyy') as hyear from emp",  con = con1)

pd.read_sql("select ename, to_char(hiredate, 'yyyy') as hyear from emp",  con = con1)
Out[149]: 
     ename hyear
0    SMITH  1980
1    ALLEN  1981
2     WARD  1981
3    JONES  1981
4   MARTIN  1981
5    BLAKE  1981
6    CLARK  1981
7    SCOTT  1987
8     KING  1981
9   TURNER  1981
10   ADAMS  1987
11   JAMES  1981
12    FORD  1981
13  MILLER  1982

 

SQLite를 사용해야하는 상황이었기에 사용이 불가능했던 to_char의 사용이 가능해졌음을 확인할 수 있다.

 

3) DBMS에 테이블 생성 (python 객체 -> DB 테이블 생성, 접속된 계정의 테이블 생성 권한 필요)
emp.to_sql(name,                # 저장할 테이블명
                   con,                   # 연결정보 (create_engine으로 만든 정보명)
                   schema,            # 테이블 소유자 (생략 시 접속한 계정 소유의 테이블 생성)
                   if_exists = 'fail'   # replace(대체), append(삽입)
                   index = True)    # 행번호 저장 여부

# 예) 새로운 데이터프레임 생성 후 DB에 테이블로 저장
from pandas import Series, DataFrame
df = DataFrame({'COL1':['A','B','C','D'], 'COL2' : [1,2,3,4]})
df.to_sql('python_tab1', con = con1, index = False)

df.to_sql('python_tab1', con = con1, index = False)
Out[153]: 4

 

 ▲ Orange에서도 새로운 데이터프레임을 조회할 수 있다.


04 array

numpy에서 제공하는 자료구조로 다차원 자료구조이다.

같은 데이터타입만 허용하며 주로 숫자들의 빠른 행렬곱을 위해 생성한다.

키구조가 아니기 때문에 DF처럼 키 별로 접근/생성하는 것은 어렵다.

 

 -01 생성

import numpy as np

a1 = np.array([1,2,3,4])
a2 = np.array([1,2,3,4], dtype = float)
a3 = np.array([[1,2,3,4],[5,6,7,8]])

a1
a2
a3

a1
Out[166]: array([1, 2, 3, 4])

a2
Out[167]: array([1., 2., 3., 4.])

a3
Out[168]: 
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

 

np.arange(1,13)

np.arange(1,13)
Out[192]: array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])

 

# 층행렬 생성
a4 = np.arange(1,25).reshape(2,3,4) # 2층, 3행, 4열 구조

a4

 

 in Python) - 행 - 열 순서

 in R) 행 - 열- 순서

 * 순서에 차이가 존재하기에 이후 3차원 데이터를 다룰 시 해당 사항을 기억해두어야 한다.

a4
Out[194]: 
array([[[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]],

       [[13, 14, 15, 16],
        [17, 18, 19, 20],
        [21, 22, 23, 24]]])

 -02 주요 매서드

dir(a1)            # numpy 객체가 호출 가능한 메서드 목록

 

a1.dtype           # 데이터 타입 확인

a1.dtype           # 데이터 타입 확인
Out[190]: dtype('int64')


a1.ndim  # 차원 확인
a3.ndim  # 차원 확인

a1.ndim
Out[170]: 1

a3.ndim  # 차원 확인
Out[171]: 2

 

a1.shape # 크기(4,) -> 1차원이기 때문에 총 갯수만 출력되며 뒷 칸은 공란으로 출력된다.
a3.shape # 크기(2,4) -> 2행 4열 구조

a1.shape # 크기(4,)
Out[172]: (4,)

a3.shape
Out[173]: (2, 4)

 

a3.shape[0] # 행 크기
a3.shape[1] # 컬럼 크기

a3.shape[0]
Out[183]: 2

a3.shape[1]
Out[184]: 4

 

a4.shape[0] # 층 크기
a4.shape[1] # 행 크기
a4.shape[2] # 열 크기

a4.shape[0] # 층 크기
Out[197]: 2

a4.shape[1] # 행 크기
Out[198]: 3

a4.shape[2] # 열 크기
Out[199]: 4

 

2차원 데이터일 때와 3차원 데이터일 때 색인의 결과가 다르므로 아래 표를 참고하면 된다.

  2차원 데이터 3차원 데이터
0
1 컬럼
2 X 컬럼

 

a1.reshape(2,2) # 크기 변경 (행 우선 순위, C가 default)

a1.reshape(2,2, order = 'C') # 크기 변경 (C 순서 : 행 우선 순위) 와 동일하다.

 +) a1.reshape(2,-1) # -1은 나머지 크기를 자동 계산

a1.reshape(2,2)
Out[174]: 
array([[1, 2],
       [3, 4]])

 

a1.reshape(2,2, order = 'F') # 크기 변경 (F 순서 : 컬럼 우선 순위)

a1.reshape(2,2, order = 'F') # 크기 변경 (F 순서 : 컬럼 우선 순위)
Out[181]: 
array([[1, 3],
       [2, 4]])

 

a3.reshape(8,)      # 2차원 -> 1차원 평탄화
a3.flatten()            # 2차원 -> 1차원 평탄화

a3.reshape(8,)      # 2차원 -> 1차원 평탄화
Out[185]: array([1, 2, 3, 4, 5, 6, 7, 8])

a3.flatten()        # 2차원 -> 1차원 평탄화
Out[186]: array([1, 2, 3, 4, 5, 6, 7, 8])

 

a3.flatten(order = 'C') # 2차원 -> 1차원 평탄화 (첫번째 행 배치 후 두번째 행 배치 순서)
a3.flatten(order = 'F') # 2차원 -> 1차원 평탄화 (첫번째 컬럼 배치 후 두번째 컬럼 배치 순서)

a3.flatten(order = 'C') # 2차원 -> 1차원 평탄화 (첫번째 행 배치 후 두번째 행 배치 순서)
Out[187]: array([1, 2, 3, 4, 5, 6, 7, 8])

a3.flatten(order = 'F') # 2차원 -> 1차원 평탄화 (첫번째 컬럼 배치 후 두번째 컬럼 배치 순서)
Out[188]: array([1, 5, 2, 6, 3, 7, 4, 8])

 -03 색인

a5 = np.arange(1,26).reshape(5,5)

a5
Out[208]: 
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25]])


a5[0,0]             # 정수 색인
a5[0:3, 0]          # 슬라이스 색인
a5[0:3, [0,2,4]]    # 리스트 색인

a5[0,0]
Out[204]: np.int64(1)

a5[0:3, 0]
Out[205]: array([ 1,  6, 11])

a5[0:3, [0,2,4]]
Out[206]: 
array([[ 1,  3,  5],
       [ 6,  8, 10],
       [11, 13, 15]])


a5[:,0] >= 10

a5[:,0] >= 10
Out[207]: array([False, False,  True,  True,  True])

 

a5[a5[:,0] >= 10, : ] # 조건 색인

a5[a5[:,0] >= 10, : ]
Out[209]: 
array([[11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25]])

 

 

딥러닝 코드 사용 시 2차원의 형태로 데이터가 전달되어야하는 경우가 있다.

reshape 혹은 slice indexing을 통해 다음과 같이 차원 축소에 관련된 문제를 해결결할 수 있다.

 

# ** 차원 축소 발생! (특정 층, 행, 컬럼 선택 시 자동으로 저차원 데이터로 출력됨)
# 예) array
a5[0,:]     # 1차원 array로 리턴
a5[:,3]     # 1차원 array로 리턴

a5[0,:]     # 1차원 array로 리턴
Out[215]: array([1, 2, 3, 4, 5])

a5[:,3]     # 1차원 array로 리턴
Out[216]: array([ 4,  9, 14, 19, 24])

 

# ** 차원 축소 방지 => slice indexing 사용
a5[0:1, :]
a5[:, 3:4]

a5[0:1, :]
Out[219]: array([[1, 2, 3, 4, 5]])

a5[:, 3:4]
Out[220]: 
array([[ 4],
       [ 9],
       [14],
       [19],
       [24]])

# 예) DataFrame
emp.iloc[0,:]       # Series로 리턴
emp.iloc[:,0]       # Series로 리턴

emp.iloc[0,:]       # Series로 리턴
Out[217]: 
EMPNO                      7369
ENAME                     SMITH
JOB                       CLERK
MGR                      7902.0
HIREDATE    1980-12-17 00:00:00
SAL                         800
COMM                        NaN
DEPTNO                       20
Name: 0, dtype: object

emp.iloc[:,0]       # Series로 리턴
Out[218]: 
0     7369
1     7499
2     7521
3     7566
4     7654
5     7698
6     7782
7     7788
8     7839
9     7844
10    7876
11    7900
12    7902
13    7934
Name: EMPNO, dtype: int64

 

emp.loc[:, 'SAL']   # Series로 리턴
emp['SAL']          # Series로 리턴

emp.loc[:, 'SAL']   # Series로 리턴
Out[228]: 
0      800
1     1600
2     1250
3     2975
4     1250
5     2850
6     2450
7     3000
8     5000
9     1500
10    1100
11     950
12    3000
13    1300
Name: SAL, dtype: int64

emp['SAL']          # Series로 리턴
Out[229]: 
0      800
1     1600
2     1250
3     2975
4     1250
5     2850
6     2450
7     3000
8     5000
9     1500
10    1100
11     950
12    3000
13    1300
Name: SAL, dtype: int64

 

# ** 차원 축소 방지 => slice indexing 사용

emp.iloc[0:1,:]       # Dataframe으로 리턴
emp.iloc[:,0:1]       # Dataframe으로 리턴

emp.iloc[0:1,:]       # Dataframe으로 리턴
Out[224]: 
   EMPNO  ENAME    JOB     MGR   HIREDATE  SAL  COMM  DEPTNO
0   7369  SMITH  CLERK  7902.0 1980-12-17  800   NaN      20

emp.iloc[:,0:1]       # Dataframe으로 리턴
Out[225]: 
    EMPNO
0    7369
1    7499
2    7521
3    7566
4    7654
5    7698
6    7782
7    7788
8    7839
9    7844
10   7876
11   7900
12   7902
13   7934

 

# 문자 슬라이스의 경우 자기 자신으로 지정해주면 된다.

emp.loc[:, 'SAL':'SAL'] 

emp.loc[:, 'SAL':'SAL']
Out[226]: 
     SAL
0    800
1   1600
2   1250
3   2975
4   1250
5   2850
6   2450
7   3000
8   5000
9   1500
10  1100
11   950
12  3000
13  1300

 

# Slice indexing이 어려운 경우 다음과 같이 대괄호를 2번 사용하여 key indexing을 진행할 수 있다.

emp[['SAL']]          # Dataframe으로 리턴

emp[['SAL']]
Out[230]: 
     SAL
0    800
1   1600
2   1250
3   2975
4   1250
5   2850
6   2450
7   3000
8   5000
9   1500
10  1100
11   950
12  3000
13  1300

ex) 두번째, 다섯번째 행의 두 번째, 네 번째 컬럼 선택하기

 

array에서 둘 이상의 리스트를 사용하여 indexing을 하는 경우 특정 포인트를 찾는 방식으로 해석된다.

 

a5[[1,4], [1,3]] 

a5[[1,4], [1,3]] 
Out[240]: array([ 7, 24])

 ▲ 2개의 값만 리턴되었음을 확인할 수 있다.
array에서 point indexing을 진행하는 경우 이러한 문제가 발생한다. (p(1,3), p(4,3)이 출력됨)

 

np.ix_를 통하여 해당 문제를 해결할 수 있다.

a5[np.ix_([1,4],[1,3])]

a5[np.ix_([1,4],[1,3])]
Out[241]: 
array([[ 7,  9],
       [22, 24]])

 ▲  두 번째, 다섯 번째 행의 두 번째, 네 번째 컬럼 선택이 가능해졌음을 확인할 수 있다.


 -04 연산
a11 = np.arange(1,5).reshape(2,2)
a12 = np.arange(10,41,10).reshape(2,2)
a13 = np.arange(10,61,10).reshape(3,2)

a11
Out[250]: 
array([[1, 2],
       [3, 4]])

a12
Out[251]: 
array([[10, 20],
       [30, 40]])

a13
Out[252]: 
array([[10, 20],
       [30, 40],
       [50, 60]])


a11 + a12  # 같은 크기의 array끼리 연산이 가능하다.

a11 + a12
Out[253]: 
array([[11, 22],
       [33, 44]])


a11 + a13  # error가 발생했다.

a11 + a13  # error가 발생했다.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[254], line 1
----> 1 a11 + a13  # error가 발생했다.

ValueError: operands could not be broadcast together with shapes (2,2) (3,2)

 

 

# ** array의 broadcast 기능
a15 = np.arange(1,3).reshape(2,1)
a11 + a15

 

작은 쪽의 array가 적어도 같은 위치(행 or 열)에 있는 shape과 같은 수를 공유해야하며, 다른 쪽은 1이어야 한다.

a11 + a15
Out[262]: 
array([[2, 3],
       [5, 6]])


 

ex) 1~12까지 값을 가지는 3,4 array 생성 (a1), 10,20,30 값을 가지는 array 생성 (a2), 10, 20, 30, 40 을 가지는 array 생성(a3)
이후 a1 + a2, a1 + a3이 가능하도록 연산

a1 = np.arange(1,13,1).reshape(3,4)
a2 = np.arange(10,31,10).reshape(3,1)
a3 = np.arange(10,41,10).reshape(1,4)

a1 + a2

a1 + a2
Out[277]: 
array([[11, 12, 13, 14],
       [25, 26, 27, 28],
       [39, 40, 41, 42]])


a1 + a3

a1 + a3
Out[280]: 
array([[11, 22, 33, 44],
       [15, 26, 37, 48],
       [19, 30, 41, 52]])

 

# 문제풀이
a1 = np.arange(1,13,1).reshape(3,4)
a2 = np.array([10,20,30])
a3 = np.array([10,20,30,40])

a1 + a2.reshape(3,1)

a1 + a3


 -05 축별 연산
import numpy as np
arr1 = np.arange(1,17).reshape(4,-1)

arr1
Out[7]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12],
       [13, 14, 15, 16]])


arr2 = np.arange(1,25).reshape(2,3,4)  # 2층 3행 4열

arr2
Out[8]: 
array([[[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]],

       [[13, 14, 15, 16],
        [17, 18, 19, 20],
        [21, 22, 23, 24]]])

 

* keepdimps 옵션 : 차원축소를 피하고 싶을 때 True로 적용하면 된다.

# ** 2차원에서의 계산
arr1.sum(axis=0) # 서로 다른 행끼리 연산 (세로방향)
arr1.sum(axis=1) # 서로 다른 행끼리 연산 (가로방향)

arr1.sum(axis=0) # 서로 다른 행끼리 연산 (세로방향)
Out[12]: array([28, 32, 36, 40])

arr1.sum(axis=1) # 서로 다른 행끼리 연산 (가로방향)
Out[13]: array([10, 26, 42, 58])

 

# ** 3차원 (층 : 0, 행 : 1, 열 : 2)
arr2.sum(axis=0) # 서로 다른 층끼리 연산
arr2.sum(axis=1) # 서로 다른 축끼리 연산
arr2.sum(axis=2) # 서로 다른 컬럼끼리 연산 (가로방향)

arr2.sum(axis=0) # 서로 다른 층끼리 연산
Out[18]: 
array([[14, 16, 18, 20],
       [22, 24, 26, 28],
       [30, 32, 34, 36]])

arr2.sum(axis=1) # 서로 다른 축끼리 연산
Out[19]: 
array([[15, 18, 21, 24],
       [51, 54, 57, 60]])

arr2.sum(axis=2) # 서로 다른 컬럼끼리 연산 (가로방향)
Out[20]: 
array([[10, 26, 42],
       [58, 74, 90]])


 -06 행/열 결합

 - np.vstact(), np.hstack()

arr3 = np.arange(1,9).reshape(2,4)

arr3
Out[28]: 
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])


arr4 = np.arange(10,81,10).reshape(2,4)

arr4
Out[29]: 
array([[10, 20, 30, 40],
       [50, 60, 70, 80]])

 

np.vstack([arr3, arr4]) # 수직방향 결합 (행추가)
np.hstack([arr3, arr4]) # 수평방향 결합 (컬럼추가)

np.vstack([arr3, arr4]) # 수직방향 결합 (행추가)
Out[30]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [10, 20, 30, 40],
       [50, 60, 70, 80]])

np.hstack([arr3, arr4]) # 수평방향 결합 (컬럼추가)
Out[31]: 
array([[ 1,  2,  3,  4, 10, 20, 30, 40],
       [ 5,  6,  7,  8, 50, 60, 70, 80]])

 

np.concatenate([arr3, arr4], axis=0) # 수직방향 결합 (행추가)
np.concatenate([arr3, arr4], axis=1) # 수직방향 결합 (열추가)

np.concatenate([arr3, arr4], axis=0) # 수직방향 결합 (행추가)
Out[46]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [10, 20, 30, 40],
       [50, 60, 70, 80]])

np.concatenate([arr3, arr4], axis=1) # 수직방향 결합 (열추가)
Out[47]: 
array([[ 1,  2,  3,  4, 10, 20, 30, 40],
       [ 5,  6,  7,  8, 50, 60, 70, 80]])