파이썬 3

ganadara·2022년 11월 10일
2

복습

목록 보기
44/49
post-thumbnail
post-custom-banner

새싹 인공지능 응용sw 개발자 양성 교육 프로그램 나예진 강사님 수업 정리 글입니다. (나예진 강사님 이메일: nayejin11@gmail.com)

목차
1. lambda
2. 패키지, 모듈, 함수의 관계도
3. numpy
4. pandas

1. lambda 함수

inline function, def라고 하는 명령어 없이 간단하게 정의해서 사용할 수 있다.

def add(a, b): #a,b 지역변수
  return a+b

def return_length(s):
  return len(s)

#lambda함수로 바뀌면
f = lambda a, b: a+ b
print(add(3, 5))
print(f(3, 5))

-> 8
8

lambda x: x + 10
-> <function __main__.<lambda>(x)>
# 익명 함수이기때문에 람다식을 변수에 할당해야 한다.

plus_ten = lambda x: x + 10
plus_ten(1)
-> 11
  • 다양한 함수 실습
#아래 리스트의 원소들을 원소들의 길이에 따라 정렬하고 싶은 경우엔 어떻게 해야할까?
strings = ['yoon', 'kim', 'jessica', 'jeong']
#strings.sort() #alphabetical order로 정렬됩니다. 사전순 정렬
strings.sort(key=lambda s:lens(s))   #len(s)은 알파벳 갯수의 기준으로 정렬된다.
strings
-> ['kim', 'yoon', 'jeong', 'jessica']

#수학 계산
import math
#절대값, 올림, 내림
print(abs(-3))
print(math.ceil(3.5))
print(math.floor(3.5))
#sin, cos
print(math.sin(1))
print(math.cos(1))

->3
4
3
3
0.8414709848078965
0.5403023058681398

#복권 숫자를 만들어 봅시다.
import random
random.sample(range(1, 46), 7)
#range = 1~46 숫자를 가지고 있는 집합, sample은 7개를 뽑아라, 
몇 개 중에 = ragne , 몇 개를 뽑아라 = sample

-> [1, 35, 11, 14, 3, 31, 40]

#다양한 사전들을 써봅시다.
from collections import defaultdict
from collections import OrderedDict

D = defaultdict(int)
D2 = OrderedDict()
D2['z'] = 26
D2['a'] = 1
D2['c'] = 3
D2['d'] = 5
D2['j'] = 14
D2['b'] = 2
D2

-> 
OrderedDict([('z', 26), ('a', 1), ('c', 3), ('d', 5), ('j', 14), ('b', 2)])

#짝수만을 출력하고 싶을 때
mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even= []


for i in mylist:
  if i % 2 == 0:
     even.append(i)

print(even)
-> [2, 4, 6, 8, 10]


2. 패키지, 모듈, 함수의 관계도

  • 함수들의 뭉쳐진 하나의 ,py파일 안에 이루어진 것을 모듈이라고 합니다.
  • 여러 개의 모듈을 그룹화 하면 패키지가 됩니다.
  • 패키지는 종종 라이브러리라고도 불리웁니다.

🧠사전 도서관 비유
도서관 = 패키지(=라이브러리)
사전 = 모듈
단어 = 함수

사전 안의 단어 하나하나 = 함수(단어)
단어 하나만은 의미가 없고 어떻게 사용할 때 의미가 있다.
함수들의 집합, 쓰고 자 하는 함수들이 모아져 있는 것 = 모듈(사전)
(도서관) = 패키지 = 라이브러리

모듈 import 하기

import 왜 할까? 다른 사람이 이미 만들어 놓은 좋은 모듈을 우리가 쉽게 가져다 쓸 수 있기 때문이다.

import하는 방법 : py(파이썬 파일 확장자)로 된 파일을 우리는 모듈이라고 한다. imprort구문을 통해 파일을 불러 올 수 있다.

import pandas

# 위의 코드는 pandas라는 모듈은 우리가 불러오겠다라는 의미이며, 
이미 colab에서 유명한 모듈은 설치가 되어 있는 상태이기 때문에, 
우리가 따로 설치할 필요없이 가져올 수 있다. 

패키지에서 import하기

패키지는 모듈의 그룹이다.

🧠직박구리폴더 예시
직박구리 폴더에 파일1이 들어있다.
직박구리 폴도 = 패키지
파일1 = 모듈

from 패키지 import 모듈
from 직박구리 import 파일1

from pandas import DataFrame 
#pandas라는 패키지 안에 Dataframe의 모듈을 가져와라
  • 별칭(alias)지어주기
    pandas라는 패키지 이름이 너무 길어서 약어로 줄여쓸 수 있다. as사용

  • 앞으로 자주 사용할 패키지, 모듈 미리보기

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sesaborn as sns

#numpy: 과학 계산을 위한 패키지
#pandas: 데이터 분석을 할 때 가장 많이 쓰이는 패키지
#matplotlib: 시각화를 위한 패키지
#seaborn: 시각화를 위한 패키지(matplotlib을 더 쉽게 사용할 수 있도록 도와주는 패키지)

3. numpy

numerical python

  • 기능
    numerical computing: 컴퓨터가 실수값을 효과적으로 계산가능
    vector arithmetic: 백터 연산 = 데이터가 벡터로 표현되기 때문 = 행열계산 = 데이터 타입이 행열 형태로 되어야 한다.
    -> 데이터 분석할 때 사용되는 pandas와 matplotlib의 기반으로 사용된다.
    numpy에서 기본적으로 array라는 단위로 데이터를 관리하며 이에 대해 연산을 수행한다.

  • numpy vs list

numpy.arraylist
한 가지 자료형만 허용여러 가지 자료형 허용
내부 배열에서 원소 개수 같아야 함내부 배열 내 원소 개수 달라도 됨
선언할 때 크기 지정하고 변경 불가(정적 할당)계속 크기가 변화 가능(동적 할당)
#list출력
list_data = [1, 2, 3]
print(list_data)

-> [1, 2, 3]

#numpy출력
import numpy as np

list_data = [1, 2, 3]
array = np.array(list_data) # =numpy형태로 바꾸는 것

print(array)
print(array.size)
print(array.dtype)
iprint(array[2])

-> [1, 2, 3]
3
int32
3

#list 연산
t1 = (1, 2, 3)
t2 = (4, 5)
t1 + t2

-> (1, 2, 3, 4, 5)

#numpy 연산
import numpy as np

arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([3, 4, 5, 6, 7])
arr1 + arr2

->array([ 4,  6,  8, 10, 12])

numpy array creation

#numpy 라이브러리를 불러옵니다.
import numpy as np 

#파이썬 리스트 선언
data = [1, 2, 3, 4, 5]
data, type(data)
-> ([1, 2, 3, 4, 5], list)

#파이썬 2차원 리스트(행렬) 선언
data2 = [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]
        
]
data2
-> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]


#파이썬 list를 numpy array로 변환
arr1 = np.array(data)
print(type(arr1)) # = <class 'numpy.ndarray'> , 이제 행렬이 되었다. 
arr1, type(arr1) #numpy.ndarray : ndarray(n-dimensional array)
# numpy array를 만드는 방식의 대부분은 파이썬 리스트를 np.array로 변환하는 방식
arr1.shape #shape = shape이 어떻게 생겼니 알려줌
# np.array.shape은 np.array의 크기를 알려줌

-> <class 'numpy.ndarray'>
(5,)

arr2 = np.array(data2)
print(arr2)
print(type(arr2))
arr2.shape #index값을 사용하지 않고 좌표값을 사용한다.

-> [[ 1  2  3]
 [ 4  5  6]
 [ 7  8 90]]
<class 'numpy.ndarray'>
(3, 3)

print("arr2의 nidm : ", arr2.ndim) #arr2의 차원
print("arr2의 shape : ", arr2.shape) #arr2의 행, 열의 크기
print("arr2의 size: ", arr2.size) #arr2의 행 x 열
print("arr2의 dtype : ", arr2.dtype) #arr2의 원소의 타입
print("arr2의 itemsize : ", arr2.itemsize) #arr2의 원소의 사이즈
print("arr2의 nbytes : ", arr2.nbytes) #itemsize * size

-> arr2의 nidm :  2
arr2의 shape :  (3, 3)
arr2의 size:  9
arr2의 dtype :  int64
arr2의 itemsize :  8
arr2의 nbytes :  72

Array Initialization

  • numpy array를 초기값과 함께 생성하는 방법
  • 원소가 0인 array를 생성하는 np.zeros()
  • 원소가 1인 array를 생성하는 np.ones()
  • 특정 범위의 원소를 가지는 np.arange()
# 0이 5개 있는 array
np.zeros(5)
-> array([0., 0., 0., 0., 0.])

# 0이 3x3인 array
np.zeros((3, 3))
-> array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])
       
# 1이 3개 있는 array
np.ones(3)
-> array([1., 1., 1.])

# 1이 2x2인 array
np.ones((2, 2))
-> array([[1., 1.],
       [1., 1.]])
       
# 0부터 9까지 숫자를 자동으로 생성한 array
np.arange(10)
-> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

# 10부터 99까지 숫자를 자동으로 생성한 array
np.arange(10, 100) # python range 함수와 동일한데, np.array 생성까지 자동으로 해줍니다.
->array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
       27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
       44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
       61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
       78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
       95, 96, 97, 98, 99])

Array Operation (like vector) --> Universal Function

numpy array를 쓰는 가장 큰 이유는 vector처럼 사용할 수 있기 때문
ex)arr1 = np.array([1, 2, 3, 4, 5]) --> (1, 2, 3, 4, 5)

vector

방향성 있는 숫자들의 집합. 주로 배열이라고 말한다.
방향성 있는 숫자들의 집합이라서 index의 개념이 나온 것이다.

대부분의 데이터 분석 라이브러리들은 벡터를 사용하는데, 그 벡터가 바로 numpy array로 표현되기 때문입니다.

데이터 분석은 99.9% 데이터를 벡터로 표현하여 분석하기 때문에, 이 특징은 굉장히 중요합니다.
벡터 == numpy array

# v1 = (1, 2, 3), v2 = (4, 5, 6) 벡터 2개 생성하기.
v1 = np.array((1, 2, 3))
v2 = np.array((4, 5, 6))
type(v1), type(v2)

>> (numpy.ndarray, numpy.ndarray)

#  vector addition
v1 + v2

>>array([5, 7, 9])

#  vector subtraction
v1 - v2

>>array([-3, -3, -3])

# (not vector operation) elementwise multiplication
v1 * v2

>>array([ 4, 10, 18])

# (not vector operation) elementwise division
v1 / v2

>>array([0.25, 0.4 , 0.5 ])

# dot product
v1 @ v2 # 1x4 + 2x5 + 3x6 = 32
>>32

boradcast

서로 크기가 다른 numpy array를 연산할 때, 자동으로 연산을 전파(broadcast)해주는 기능. 행렬곱 연산을 할 때 편리하다.

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

>> (2, 3) # 2행 3열


arr2 = np.array([7, 8, 9])
arr2.shape

>>(3,) # 

# 2개의 array를 더해보면?
arr1 + arr2 # [1, 2, 3] + [7, 8, 9] // [4, 5, 6] + [7, 8, 9]

>>array([[ 8, 10, 12],
       [11, 13, 15]])
      
# 2개의 array를 곱해보면? (**)
arr1 * arr2 # [1, 2, 3] * [7, 8, 9] // [4, 5, 6] * [7, 8, 9]
# [1, 2, 3]  X  [7]
# [4, 5, 6]     [8]
#               [9]

>>array([[ 7, 16, 27],
       [28, 40, 54]])
       
# arr1에 10을 곱해보면?
arr1 * 10 # vector scalar multiplication

>>array([[10, 20, 30],
       [40, 50, 60]])
       
# arr1을 제곱해보면?
arr1 * arr1

>>array([[ 1,  4,  9],
       [16, 25, 36]])

universal functions

numpy array는 하나의 함수를 모든 원소에 자동으로 적용해주는 Universal Function이라는 기능을 제공한다. 이 덕분에 모든 원소에 대해 같은 작업을 처리할 때 엄청나게 빠른 속도를 낼 수 있다.

arr1 = np.array([1, 2, 3])
arr1 = arr1 / 1
#arr1.dtype

# 모든 원소를 역수를 취하려면 어떻게 해야할까?
1 / arr1 # 각 원소에 1 / 라는 operation을 모두 적용하는 연산이 됩니다

>>array([1.        , 0.5       , 0.33333333])

# 모든 원소에 2를 더하려면 어떻게 해야할까?
arr1 + 2

>>array([3., 4., 5.])

indexing

arr1 = np.arange(10)
arr1

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

# 첫번째 원소
arr1[0]
>>0

# 마지막 원소
arr1[-1]
>>9

# 앞에서부터 원소 3개 slicing
arr1[:3]
>> array([0, 1, 2])

arr2 = np.array([[1, 2, 3, 4],
               [5, 6, 7, 8],
               [9, 10, 11, 12]])
arr2
>>array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
       
# arr2의 2, 3 원소 = 7
arr2[1, 2]
>> 7

# arr2의 세번째 columnm (3, 7, 11)
arr2[:, 2] # arr2에 있는 모든 row에 대해서 3번째 원소를 indexing --> numpy array
# arr2[0, 2]
# arr2[1, 2]
# arr2[2, 2]

>>array([ 3,  7, 11])

# arr2의 두번째 row
#arr2[1]
arr2[1, :] # arr2에 있는 두번째 row에 대해서 모든 원소를 indexing --> numpy array

>> array([5, 6, 7, 8])

masking

mask = np.array([1, 0, 0, 1, 1, 0, 0])
mask

>>array([1, 0, 0, 1, 1, 0, 0])

data = np.random.randn(7, 4)
data
>>array([[ 1.92952526,  0.16811586, -0.54101152,  0.01775069],
       [-0.01501298, -0.49388391, -0.73565307,  0.07600854],
       [-0.01667803,  1.89936971, -0.04026871,  0.90275741],
       [ 2.02695639,  0.0905108 , -0.33656963, -0.44864434],
       [-0.05168743,  0.69968886, -1.85008029, -1.48106361],
       [ 0.53789872,  1.30805042,  1.27204837,  0.02936776],
       [ 0.82310049, -0.27940677, -0.8763139 , -0.474734  ]])
       
data.shape
>>(7, 4)

# mask 만들기
masked_data = (mask == 1)
masked_data

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

# 위에서 생성한 data에 mask를 적용해본다.
data[masked_data, :]

>>array([[ 1.92952526,  0.16811586, -0.54101152,  0.01775069],
       [ 2.02695639,  0.0905108 , -0.33656963, -0.44864434],
       [-0.05168743,  0.69968886, -1.85008029, -1.48106361]])
    
# 마스크를 0으로 바꿔본다.
data[mask == 0, :]

>> array([[-0.01501298, -0.49388391, -0.73565307,  0.07600854],
       [-0.01667803,  1.89936971, -0.04026871,  0.90275741],
       [ 0.53789872,  1.30805042,  1.27204837,  0.02936776],
       [ 0.82310049, -0.27940677, -0.8763139 , -0.474734  ]])
       
# fancy indexing을 이용해서 masking
#data[:, 0] < 0
data[:, 0] < 0 # 7 x 1의 mask == 첫번째 column의 원소중에 0보다 작은 원소들의 위치가 True.

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

# fancy indexing의 또 다른 방법
data[data[:, 0]<0, 0]
>>  array([-0.01501298, -0.01667803, -0.05168743])

data < 0
>>array([[False, False,  True, False],
       [ True,  True,  True, False],
       [ True, False,  True, False],
       [False, False,  True,  True],
       [ True, False,  True,  True],
       [False, False, False, False],
       [False,  True,  True,  True]])
       
data[data < 0] = 0 # 2차원 data에서 첫번째 column에 0보다 작은 원소들을 0으로 치환해주세요.
data
>> array([[1.92952526, 0.16811586, 0.        , 0.01775069],
       [0.        , 0.        , 0.        , 0.07600854],
       [0.        , 1.89936971, 0.        , 0.90275741],
       [2.02695639, 0.0905108 , 0.        , 0.        ],
       [0.        , 0.69968886, 0.        , 0.        ],
       [0.53789872, 1.30805042, 1.27204837, 0.02936776],
       [0.82310049, 0.        , 0.        , 0.        ]])



Reshaping array

x = np.array([[1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]])
x
>>array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
       
# x를 3x3 행렬로 변형합니다.
x1 = np.arange(1, 10).reshape(3, 3)
x1
>>array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
       
x == x1
>>array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]])

# (1, 2, 3)을 transpose 해봅니다.
x2 = np.array([1, 2, 3]).reshape(3, 1) # row vector -> column vector
x2
>>array([[1],
       [2],
       [3]])

4. pandas

pandas는 정형 데이터 처리에 특화되어 있다. pandas 역시 다양한 머신러닝 라이브러리들에 의존성을 가지고 있다. 간단하게 생각하면, python에서 excel의 기능을 사용할 수 있게 됩니다.

-> pandas에서column을 지정할 수 있다.

pandas 라이브러리에서 기본적으로 데이터를 다루는 단위는 dataframe이다.

pandas의 기본 자료구조(series, dataframe)

#pandas 라이브러리를 불러옵니다. pd를 약칭으로 사용합니다.
import pandas as pd #data 하나를 series라고 한다. series의 모임이 곧 datagrame이 된다. #dataframe은 2차원 테이블이고, 테이블의 한 줄을 series라고 한다.
import numpy as np
print(pd.__version__)

>>1.3.5

#s는 1, 3, 5, np.na, 6, 8을 원소로 가지는 pandas.series
s = pd.Series([1, 3, 5, np.nan, 6, 8])
s

>>0    1.0
1    3.0
2    5.0
3    NaN
4    6.0
5    8.0
dtype: float64

#20210101부터 6일간의 날짜 범위를 생성하는 pandas.date_range
dates = pd.date_range('20210101', periods = 6)
dates

>>DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04',
               '2021-01-05', '2021-01-06'],
              dtype='datetime64[ns]', freq='D')
  • index = 원하는 곳의 데이터를 가져오기 위한 수단
    dataframe의 index는 숫자형일 필요가 없다. 사용자화, 커스텀화가 가능하다.
    index값은 그 곳의 값은 중첩이 되면 안 된다.

index값 확인= df.index

df.index

>>DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04',
               '2021-01-05', '2021-01-06'],
              dtype='datetime64[ns]', freq='D')
              
df.columns

>>Index(['A', 'B', 'C', 'D'], dtype='object')

#dataframe에 대한 전체적인 요약정보를 보여줍니다. index, columns, null/not-null/dtype/memory usage가 표시됩니다.
df.info()

>><class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 6 entries, 2021-01-01 to 2021-01-06
Freq: D
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   A       6 non-null      float64
 1   B       6 non-null      float64
 2   C       6 non-null      float64
 3   D       6 non-null      float64
dtypes: float64(4)
memory usage: 240.0 bytes

  • DataGrame indexing
    indexing: 데이터에서 어떤 특정 조건을 만족하는 원소를 찾는 방법 전체 dataframe에서 조건에 만족하는 데이터를 쉽게 찾아서 조작할 때 유용하게 사용할 수 있습니다.
#pandas datagrame은 column 이름을 이용하여 기본적인 indexing이 가능
#column A를 indexing
df["A"] #dataframe에 바로 indexing을 사용하면, column을 찾습니다.
# == "key"를 indexing. == "key" == "column"

# df["2021-01-01"]

>> 2021-01-01   -2.335166
2021-01-02    1.863117
2021-01-03    2.053549
2021-01-04    0.357407
2021-01-05   -0.358786
2021-01-06   -0.037734
Freq: D, Name: A, dtype: float64

#특정날짜를 통한 indexing
df.loc['2021-01-03'] #pd.series
>>A    2.053549
B   -0.107848
C   -0.420052
D   -1.373987
Name: 2021-01-03 00:00:00, dtype: float64

#특정 위치를 통한 indexing, 숫자를 가져올 수 있다
df.iloc[2]
>>A    2.053549
B   -0.107848
C   -0.420052
D   -1.373987
Name: 2021-01-03 00:00:00, dtype: float64

df.loc['2021-01-02']
>>A    1.863117
B   -0.622961
C   -0.163947
D    0.454989
Name: 2021-01-02 00:00:00, dtype: float64

#df.loc는 특정값을 기준으로 indexing합니다 (key - value)
#2013-01-01값을 가지는 row을 가져옵니다.
df.loc[dates[0]] #df.loc[]
>> A   -2.335166
B    0.171624
C   -1.117064
D    1.006057
Name: 2021-01-01 00:00:00, dtype: float64

df['A'] > 0
>>2021-01-01    False
2021-01-02     True
2021-01-03     True
2021-01-04     True
2021-01-05    False
2021-01-06    False
Freq: D, Name: A, dtype: bool

df.loc[:, 'A'] > 0
>> 2021-01-01    False
2021-01-02     True
2021-01-03     True
2021-01-04     True
2021-01-05    False
2021-01-06    False
Freq: D, Name: A, dtype: bool

df[df["A"] > 0]["B"] #A값이 0보다 큰 B값을 뽑을 꺼야
>> 2021-01-02   -0.622961
2021-01-03   -0.107848
2021-01-04   -0.670047
Freq: D, Name: B, dtype: float64

df['A'][df["A"]>0]
>>2021-01-02    1.863117
2021-01-03    2.053549
2021-01-04    0.357407
Freq: D, Name: A, dtype: float64

profile
DL 공부중
post-custom-banner

0개의 댓글