본문 바로가기

6.Numpy | Pandas | Crawling

5/18(목) IT K-DT(55일차) / 1.numpy~2-4.DataFrame기본정보

 

 

1. NumPy(넘파이)

 

1-1. NumPy의 개요

NumPy는 Python의 수학/과학 컴퓨팅 패키지로, 다차원 배열/배열기반 계산을 지원하는 라이브러리. "Numerical Python"의 약어로, 수치 계산을 위한 강력한 도구로 널리 사용됨.

핵심 기능은 다차원 배열인 'ndarray'로, 동일한 타입의 요소들로 구성된 n차원의 배열(자료구조).

Python의 '리스트'와 비슷한 구조이나 빠른 속도, 적은 메모리의 사용, 연속적인 저장의 특징이 있음.

→ 데이터에 효율적인 접근과 연산을 가능케 함.


배열의 요소 간 사칙/제곱연산을 원소 단위로 수행할 수 있도록 다양한 수학적 연산 또한 지원함.


다른 과학 및 데이터 분석 라이브러리들과의 호환성이 좋고,

많은 python 패키지들이 NumPy 배열을 입력으로 받아들임

→ 데이터의 효율적인 처리와 분석에 유용하게 활용됨.



# numpy의 설치
! pip install numpy

# numpy 불러오기 및 np로 별명 부여
import numpy as np

 

1-2. ndarray

비교를 위해 일반적인 리스트를 선택해봄.


list1 = [1,2,3,4]
list2 = [{1,2,3,4},{5,6,7,8}]

============================================

print(list1);
print(list2);

print(type(list1));
print(type(list1[1]));
print(type((list2)));

============================================

[1, 2, 3, 4]
[{1, 2, 3, 4}, {5,6,7,8}]

<class 'list'>
<class 'int'>
<class 'list'>

 

ndarray는 n dimension array의 약어로, 'n차원 배열'이라는 의미임.

리스트랑 달리 타입은 numpy.ndarry이다.


ndarr1 = np.array([1,2,3,4]);

============================================

print(ndarr1);
print(type(ndarr1)); # ndarray = n dimension array (n차원의 배열)

============================================

[1 2 3 4]
<class 'numpy.ndarray'>

 

리스트를 ndarray로 변환하는 방법

np.array([리스트])


list1 = [1,2,3,4]
list2 = [{1,2,3,4},{5,6,7,8}]

ndarr1 = np.array(list1)
ndarr2 = np.array(list2)

============================================


print(ndarr1);
print(ndarr2);
print(type(ndarr1));
print(type(ndarr2));

============================================

[1 2 3 4]
[{1, 2, 3, 4} {5,6,7,8}]
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>

 

1-3. ndarray의 data type

python의 리스트와 달리 배열의 특징에 따라 1개의 단일 데이터 타입만 허용함.

같은 type끼리만 저장이 가능.

비교를 위해 일반적인 리스트를 선택해봄.


list1= [1, 3.14, 'Python', '💖', True]; # list이므로 각각 다른 타입의 데이터라도 저장이 가능함.

print(list1);
print(list1[3]);

============================================

[1, 3.14, 'Python', '💖', True]
💖


ndarr1 = np.array([ 1 , 2 , 3 , 4 ])

ndarr2 = np.array([ 1 , 2 , 3.14 , 4 ])
ndarr3 = np.array([ 1 , 2 , 3.14 , True ]);
ndarr4 = np.array([ '1' , 2 , 3.14 , True ])


print(ndarr1);

print(ndarr2); # 정상적으로 출력이 되며, 모두 float 타입으로 저장됨. (현재 보유중인 요소 중 가장 큰 데이터타입으로 저장됨.)
print(ndarr3); # float가 가장 큰 타입이므로 float가 출력, boolean 이 가장 작음.

print(ndarr4);

ndarr4 # 데이터타입이 Unicode 32bit type으로 저장이 됨.

============================================

[1 2 3 4]
[1.   2.   3.14 4.  ]
[1.   2.   3.14 1.  ]
['1' '2' '3.14' 'True']

array(['1', '2', '3.14', 'True'], dtype='<U32')

데이터타입의 변경

np.array([리스트], dtype=타입)


ndarr3 = np.array([1, 2, 3.14, True], dtype=int) # 데이터타입을 모두 int로 변경
ndarr3
ndarr4 = np.array(['1', 2, 3.14, True], dtype=int) # 데이터타입을 모두 int로 변경
ndarr4

ndarr4 = np.array(['1', '2', '3.14', 'True'], dtype=int) # 모두 작은따옴표 처리할 시, 에러 발생

============================================

array([1, 2, 3, 1])
array([1, 2, 3, 1])


1-4. ndarray 슬라이싱


ndarr1 = np.array(['😊','😂','🤣','😍'])
ndarr1

============================================

array(['😊', '😂', '🤣', '😍'], dtype='<U1')

 

# 배열의 행과 열을 확인.

배열.shape


ndarr1 = np.array(['😊','😂','🤣','😍'])
ndarr1.shape

============================================

(4,)  # ndarr1이 4행이라는 의미.

 

# 인덱싱

일반적인 리스트의 인덱싱과 동일.

배열 [ 인덱싱번호 ]


ndarr1 = np.array(['😊','😂','🤣','😍'])

print(ndarr1[0])
print(ndarr1[3])
print(ndarr1[-1])
print(ndarr1[-2])

============================================

😊
😍
😍
🤣

 

# 슬라이싱

일반적인 리스트의 슬라이싱과 동일.

배열 [ 시작 인덱싱번호 : 끝 직전 인덱싱번호 ]


ndarr1 = np.array(['😊','😂','🤣','😍'])

print(ndarr1[0:2])
print(ndarr1[2:])
print(ndarr1[:2])

============================================

['😊' '😂']
['🤣' '😍']
['😊' '😂']


# 0행 가져오기

배열 [ 0 , : ]


ndarr2d = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])

print(ndarr2d[0])

print(ndarr2d[0,])
print(ndarr2d[0,:])  

============================================

[1 2 3 4]
[1 2 3 4]
[1 2 3 4]

 

# 0열 가져오기

배열 [ : , 0 ]


ndarr2d = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])

print(ndarr2d[:,0]) 

============================================

[1 5 9]

 

1-5. Fancy 인덱싱

특정 index의 집합의 값들을 선택해서 추출하고 싶은 경우,

배열의 요소에 접근하기 위해 정수 배열 또는 boolean 배열을 사용함.

 

배열 [  [인덱스집합]  ]


ndarr1 = np.array([10,15,2,8,20,90,85,44,23,32]);
idx = [2,5,9];

ndarr2d = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])

============================================

print(ndarr1[idx]);  # ndarr1의 index 2번, 5번, 9번을 뽑아내겠다는 의미.

print(ndarr2d[[0,1],:]);  # ndarr2의 0번, 1번 index인 배열의 열 전체를 뽑아내겠다는 의미.


============================================

[ 2 90 32] 

[[1 2 3 4]
 [5 6 7 8]]

 

1-6. Boolean 인덱싱

조건에 대한 필터링을 통해 Boolean값을 이용한 색인을 사용.

 


ndarr1 = np.array(['😊','😂','🤣','😍'])

selValue = [True, False, True, False]

============================================

print(ndarr1[selValue]);   # True인 값들만 뽑아옴. 여기서는 이모티콘 '😊', '🤣'.

============================================

['😊' '🤣']



 # 갖고있는 요소가 7보다 큰 요소는 True, 아니라면 False로 출력
ndarr2d = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])

============================================

# 7보다 큰 요소를 모두 출력
ndarr2d>7

ndarr2d[ndarr2d>7] 

============================================

array([[False, False, False, False],
          [False, False, False,  True],
          [True,  True,  True,  True]])

array([ 8,  9, 10, 11, 12])

 

1-7. 행렬 연산

1-7-1. 연산자

덧셈 뺄셈 곱셈 나눗셈은 shape가 동일해야하며, 같은 position끼리 연산함.


a = np.array([[1,2,3],
                     [2,3,4]])
b = np.array([[3,4,5],  
                     [1,2,3]])

a.shape, b.shape # 만약 shape가 다르면(=행, 열이 다르면) 에러가 발생함.

# 덧셈연산

a+b

# 뺄셈연산

a-b

 # 곱셈연산

a*b

#나눗셈연산

a/b

============================================

((2, 3), (2, 3)) # shape가 동일하므로 연산에 문제가 없음.

array([[4, 6, 8],
          [3, 5, 7]])

array([[-2, -2, -2],
          [ 1,  1,  1]])

array([[ 3,  8, 15],
          [ 2,  6, 12]])

array([[0.33333333, 0.5       , 0.6              ],
          [2.                , 1.5       , 1.33333333]])

 

1-7-2. 내적

행렬 곱셈이라고도 불리며, 두 행렬을 곱한 결과를 계산하는 연산.

내적을 수행하기 위해서는 '첫 번째 행렬의 열 수'와 '두 번째 행렬의 행 수'가 일치해야 함.
행렬 곱셈의 일반적인 형태이며, NumPy에서는 np.dot() 함수를 사용하여 내적 연산을 수행할 수 있음.

또는 @ 연산자를 사용하여 행렬 곱셈을 수행할 수도 있음.

 

 np.dot(행렬A, 행렬B)


a = np.array([[1,2,3],
                      [1,2,3],
                      [2,3,4]])
b = np.array([[1,2],
                      [3,4],
                      [5,6]])

a.shape, b.shape   # (3, 3), (3, 2)에서 중간의 3), (3 인 부분의 숫자가 동일해야 내적계산이 성립됨.

print((1*1)+(2*3)+(3*5), (1*2)+(2*4)+(3*6),
        (1*1)+(2*3)+(3*5), (1*2)+(2*4)+(3*6),
        (2*1)+(3*3)+(4*5), (2*2)+(3*4)+(4*6))

np.dot(a,b)

============================================

((3, 3), (3, 2))


22 28 22 28 31 40

array([[22, 28],
          [22, 28],
          [31, 40]])

 

1-7-3. arrange()

순차적인 값을 생성

np.arrange( 시작값 , 끝 직전값 )

 

시작값은 배열의 첫 번째 요소의 값이며, 끝 직전값은 배열의 마지막 요소의 다음 값.

= 생성된 배열은 시작값 이상이고, 끝 직전값 미만인 범위의 값을 가짐.

python의 range와의 비교


arr1 = range(1,11)    # range(): 범위를 확인해주는 내장함수

print(arr1)

for i in arr1:
  print(i, end=" ")   # 1부터 arr1 직전(=10)까지를 출력해주는 for문


============================================

range(1, 11)

12345678910



arr2 =  np.arange(1,11);
print(arr2)

for i in arr2:
  print(i, end=" ");

============================================

array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])

12345678910

 

1-7-4. sort()

배열의 오름차순

np.sort( 배열 )

 

배열의 내림차순

np.sort( 배열 )[::-1]


ndarr1 = np.array([1,10,5,7,2,4,3,6,8,9])

============================================

ndarr1
np.sort(ndarr1) # 오름차순 정렬
ndarr1 # inplace연산이 되지 않기 때문에, 오름차순 정렬이 초기화됨.
np.sort(ndarr1)[::-1] # reverse=True 속성이 없기때문에, 다른 방법을 이용해서 내림차순 진행.(아래 내용 참고)

============================================

array([ 1, 10,  5,  7,  2,  4,  3,  6,  8,  9])

array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
array([ 1, 10,  5,  7,  2,  4,  3,  6,  8,  9])
array([10,  9,  8,  7,  6,  5,  4,  3,  2,  1])


# 문자열 역순으로 출력하기
str1 = 'Python'

============================================

print(str1[:]) # 모든 문자를 슬라이싱
print(str1[::]) # 정방향 출력
print(str1[::-1]) # 역방향 출력
print(str1[4:1:-1]) # 4에서 1직전까지 역방향 출력
print(str1[4::-1]) # 4에서 끝까지 역방향 출력

============================================

Python
Python
nohtyP
oht
ohtyP

 

오름차순 행 정렬

np.sort(행렬, axis=0)

 

오름차순 열 정렬

np.sort(행렬, axis=1)

 

내림차순 열 정렬

np.sort(행렬, axis=1)[: , ::-1]

 


ndarr2d = np.array([[11,10,12,9],
                                [3,1,4,2],
                                [5,6,7,8]])

============================================

ndarr2d.shape

np.sort(ndarr2d, axis=0)
np.sort(ndarr2d, axis=1)
np.sort(ndarr2d, axis=1)[:,::-1]


============================================

(3, 4)

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

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

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

 

1-7-5. 숫자의 단일연산


 a = np.array([[1,2,3],
                       [4,5,6]])

============================================

a+3

a-3

a*3

a/3

============================================

array([[4, 5, 6],
          [7, 8, 9]])

array([[-2, -1,  0],
          [ 1,  2,  3]])

array([[ 3,  6,  9],
          [12, 15, 18]])

array([[0.33333333, 0.66666667, 1.        ],
          [1.33333333, 1.66666667, 2.        ]])

 

2. Pandas(판다스)

pandas는 파이썬에서 데이터 조작과 분석을 위한 빠르고 유연한 도구를 제공하는 오픈 소스 라이브러리. "Python Data Analysis Library"의 약자로, 데이터 구조와 데이터 조작을 위한 다양한 기능을 포함함.

pandas는 데이터를 효과적으로 다루기 위한 두 가지 주요 데이터 구조를 제공함. 

 

첫 번째는 'Series'로, 일련의 값과 인덱스로 구성된 1차원 배열.

python의 리스트나 1차원 배열과 유사하나, 각 요소에 라벨을 붙일 수 있어 데이터의 의미를 이해하기 용이. 

두 번째는 'DataFrame'으로, 행과 열로 구성된 2차원 테이블 형태의 데이터 구조.

스프레드시트나 SQL 테이블과 유사한 형태로 데이터를 조직할 수 있으며, 여러 가지 데이터 타입을 지원함.

데이터 조작, 필터링, 결합, 그룹화, 정렬 등 다양한 작업을 수행할 수 있는 강력한 도구.

또한, NumPy와 함께 사용되어 NumPy의 배열을 기반으로 하는 계산과 데이터 조작을 더욱 효율적으로 수행.

pandas는 데이터의 가공, 정제, 탐색, 시각화 등 다양한 작업을 편리하게 수행할 수 있으며,

다른 파이썬 라이브러리와의 호환성이 뛰어나기 때문에 데이터 분석 작업에 널리 활용됨.
데이터작업을 쉽고 직관적으로 할 수 있게 설계된 빠르고 유연한 데이터 구조(데이터프레임)를 제공.

 

2-1. Series와 DataFrame

* 2차원 표 데이터: 데이터프레임 = colums + index
* 1차원 표 데이터: 시리즈 = colums + index + values
* 표 데이터 부분: values
* 표 행 이름: index
* 표 열 이름: columns
* 데이터프레임, 시리즈: numpy의 ndarray 기반

!pip install pandas
import pandas as pd

# 데이터 만들기
data1 = [[67,93,91],
              [75,69,96],
              [75,81,82],
              [62,70,75],
              [98,45,87]]

# 인덱스 만들기
idx1 = ['김사과', '반하나', '오렌지', '이메론', '배애리']

# 행 만들기
col1 = ['국어','영어','수학']

 

# List를 사용하여 데이터프레임 만들기
#DataFrame(데이터, 인덱스, 컬럼)으로 만들 수 있음.
pd.DataFrame(data1, idx1, col1)

 

 

# 데이터프레임 내에서 파라미터를 통해 명시해줄 수 있음. → 굳이 순서를 맞출 필요 없음.
pd.DataFrame(data=data1, columns=col1)
df1 = pd.DataFrame(data1, idx1, col1)

 

# 데이터프레임을 array로 출력
df1.values
df1.index
df1.columns

 

 

# 시리즈 만들기
data2 = [67, 75, 75, 62, 98]

# Series(데이터, 인덱스)
pd.Series(data2)
pd.Series(data2, idx1)
se1 = pd.Series(data2, idx1)
se1.values
se1.index

 

 

# 딕셔너리를 사용하여 DataFrame 생성
dic1 = {
    '국어':[67, 75, 75, 62, 98],
    '영어':[93, 69, 81, 70, 45],
    '수학':[91, 96, 82, 75, 87]
}

df2 = pd.DataFrame(data=dic1, index=idx1)
df2

 




csv파일, xlsx파일을 이용하여 DataFrame화 예제 실습

 

교육 간 사용할 csv 및 엑셀파일

korean-idol.xlsx
0.01MB
korean-idol.csv
0.00MB

 

2-2. CSV 파일 읽어오기

CSV 
Comma Seperaated Value의 약자로, 데이터를 쉼표로 구분한 파일. 
Excel로 로딩이 가능하지만 Excel파일과는 엄연히 다른 파일.
쉼표로 구분된 CSV가 Excel보다 더 가볍기 때문에 데이터로 많이 사용.
(공공데이터 포털에서도 CSV 포맷의 파일을 제공中)

 

# pd.read_csv(CSV파일, 인코딩방법)

pd.read_csv('korean-idol.csv')

pd.read_csv('/content/drive/MyDrive/K-DT/python_데이터분석/korean-idol.csv')
pd.read_csv('http://bit.ly/ds-korean-idol')

 

2-3. Excel파일 읽어오기

 

pd.read_excel('/content/drive/MyDrive/K-DT/python_데이터분석/korean-idol.xlsx')

 

 

2-4. DataFrame 기본정보 알아보기

 

df = pd.read_csv('http://bit.ly/ds-korean-idol')
df

 

 

type(df)          # type이 DataFrame이다.


pandas.core.frame.DataFrame

 

df.info()           # info(): 기본적인 행(row), 열(column)의 정보를 보여줌


<class 'pandas.core.frame.DataFrame'>
RangeIndex: 15 entries, 0 to 14
Data columns (total 8 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   이름       15 non-null     object 
 1   그룹       14 non-null     object 
 2   소속사      15 non-null     object 
 3   성별       15 non-null     object 
 4   생년월일     15 non-null     object 
 5   키        13 non-null     float64
 6   혈액형      15 non-null     object 
 7   브랜드평판지수  15 non-null     int64  
dtypes: float64(1), int64(1), object(6)
memory usage: 1.1+ KB

 

2-4-1. 열(column) 다루기

 

df.columns

 

Index(['이름', '그룹', '소속사', '성별', '생년월일', '키', '혈액형', '브랜드평판지수'], dtype='object')

new_columns = ['name', 'group', 'company', 'gender', 'birthday', 'height', 'blood', 'brand']
df.columns = new_columns
df

 

 

2-4-2. 통계정보 알아보기

 

# describe(): 통계 정보를 출력
df.describe()

 

 

df.describe(include=object)

 

 

2-4-3. 형태(shape) 알아보기

 

df.shape


(15, 8)

 

2-4-4. 원하는 개수의 데이터 보기

head(): 상위 5개의 row 출력
head(n): 상위 n개의 row 출력
tail(): 하위 5개의 row 출력
tail(n): 하위 n개의 row 출력

 

df.head(7)     # 상위 7개의 데이터 확인



 

df.tail(5)       # 하위 5개의 데이터 확인