넘파이
▷ndarray: N차원 배열 객체


▷ndarray 생성
넘파이 모듈의 array() 함수로 생성하며 인자로 주로 파이썬 list를 입력한다.


▷ndarray 형태와 차원

ndarray의 shape는 ndarray.shape 속성으로, 차원은 ndarray.ndim 속성으로 알 수 있다.
ndarray 배열의 shape 변수는 ndarray의 크기, 즉 행과 열의 수를 튜플 형태로 가지고 있으며 이를 통해 ndim을 사용 하지 않고 바로 ndarray 배열의 차원을 알 수 있다.(shape안의 숫자 개수를 통해 차원을 바로 알 수 있음, 리스트의 형태를 보고도 차원을 바로 알 수 있음)


▷ndarray 데이터 타입
- ndarray내의 데이터값은 숫자 값, 문자열 값, 불 값 등이 모두 가능하다.
- ndarray내의 데이터 타입은 그 연산의 특성상 같은 데이터 타입만 가능하다. 즉, 한개의 ndarray 객체에 int와 float이 함께 있을 수 없다.
- 만약 다른 데이터 유형이 섞여 있는 리스트를 ndarray로 변경하면 데이터 크기가 더 큰 데이터 타입으로 형 변환을 일괄 적용한다.
- ndarray내의 데이터 타입은 ndarray.dtype으로 확인한다.


▷ndarray 데이터 타입 변환
- ndarray.astype()을 이용하여 ndarray 내 데이터값의 타입을 변환하고, 변경을 원하는 타입을 astype()에 인자로 입력한다.
- 대용량 데이터를 다룰 시 메모리 절약을 위해서 형변환을 한다.
→파이썬 기반의 머신러닝 알고리즘은 대부분 메모리로 데이터를 전체 로딩한 다음 이를 기반으로 알고리즘을 적용하기 때문에 대용량의 데이터를 로딩할 때는 수행속도가 느려지거나 메모리 부족으로 오류가 발생할 수 있다.
→가령 int형으로 충분한 경우인데, 데이터 타입이 float라면 int형으로 바꿔서 메모리를 절약할 수 있다.


▷ndarray를 편리하게 생성하기-arange, zeros, ones
특정 크기와 차원을 가진 ndarray를 연속값이나 0또는 1로 초기화 생성해야 할 경우 arange(), zeros(), ones()를 이용해 쉽게 ndarray를 생성할 수 있다. 주로 테스트용으로 데이터를 만들거나 데이터를 일괄적으로 초기화해야 할 경우에 사용된다.

●arange()는 array를 range()로 표현한 것이다. default 함수 인자는 stop값이며, 0부터 stop값-1까지의 연속 숫자 값으로 구성된 1차원 ndarray를 만들어 준다. 여기서는 stop값만 부여했으나 range와 유사하게 start값과 step을 활용할 수도 있다.
●zeros()와 ones()는 함수 인자로 튜플 형태의 shape값을 입력하면 모든 값을 0이나 1로 채운 해당 shape를 가진 ndarray를 반환한다. 그리고 dtype을 정해주지 않으면 default로 float64 형의 데이터로 ndarray를 채운다.


▷ndarray의 차원과 크기를 변경하는 reshape()
●reshape()는 ndarray를 특정 차원 및 형태로 변환한다. 변환 형태를 함수 인자로 부여하면 된다.

●reshape(-1,5)와 같이 인자에 -1을 부여하면 -1에 해당하는 axis의 크기는 가변적이되 -1이 아닌 인자값(여기서는 5)에 해당하는 axis 크기는 인자값으로 고정하여 ndarray의 shape를 변환한다.

●reshape()는 reshape(-1,1), reshape(-1,)과 같은 형식으로 변환이 요구되는 경우가 많다. 주로 머신러닝 API의 인자로 1차원 ndarray를 명확하게 2차원 ndarray로 변환하여 입력하기를 원하거나, 또는 반대의 경우가 있을 경우 reshape()를 이용하여 ndarray의 형태를 변환시켜 주는데 사용된다.


★ndarray의 axis 축 이해
강의 'ndarray의 axis 축 이해' 참고(axis는 엄청 헷갈리기 때문에 이론이 생각안나면 다음 강의 참고)


▷ndarray의 데이터 세트 선택하기-인덱싱(Indexing)

1. 단일 값 추출
- 1차원 ndarray
●ndarray는 axis를 기준으로 0부터 시작하는 위치 인덱스값을 가지고 있다. 해당 인덱스 값을 []에 명시하여 단일 값을 추출한다. 마이너스가 인덱스로 사용되면 맨 뒤에서부터 위치를 지정한다.

- 2차원 ndarray
●1차원과 다차원 ndarray에서의 데이터 접근의 차이는 콤마(,)로 분리된 인덱스를 통해 접근하는 것이다. 즉, 2차원의 경우 콤마로 분리된 로우와 컬럼 위치의 인덱스를 통해 접근한다.

2. 슬라이싱(Slicing)
- 1차원 ndarray
●슬라이싱은 :을 이용하여 연속된 값을 선택한다.

- 2차원 ndarray
●2차원 ndarray에서의 슬라이싱도 1차원 ndarray에서의 슬라이싱과 유사하며, 단지 콤마(,)로 로우와 컬럼 인덱스를 지칭하는 부분만 다르다.

3. 팬시 인덱싱
- 1차원 ndarray
●팬시 인덱싱은 리스트나 ndarray로 인덱스 집합을 지정하면 해당 위치의 인덱스에 해당하는 ndarray를 반환하는 인덱싱 방식이다.

- 2차원 ndarray
●위의 인덱싱과 마찬가지로 콤마(,)로 로우와 컬럼 인덱스를 지칭하는 부분만 다르다.

4. 불린 인덱싱
●불린 인덱싱은 조건 필터링과 추출을 동시에 할 수 있기 때문에 매우 자주 사용되는 인덱싱 방식이다.


▷배열의 정렬-sort()와 argsort()
-넘파이 sort() 유형
1. np.sort(ndarray): 인자로 들어온 원 행렬은 그대로 유지한 채 원 행렬의 정렬된 행렬을 반환
2. ndarray.sort(): 원 행렬 자체를 정렬한 형태로 반환하며 반환 값은 None
np.sort()나 ndarray.sort() 모두 기본적으로 오름차순으로 행렬 내 원소를 정렬한다. 내림차순으로 정렬하기 위해서는 [::-1]을 적용한다. np.sort()[::-1]과 같이 사용하면 된다.
⊙배열이 2차원 이상일 경우에 axis 축 값 설정을 통해 로우 방향, 또는 컬럼 방향으로 정렬을 수행할 수 있다.

-argsort()
원본 행렬 정렬 시 정렬된 행렬의 원래 인덱스를 필요로 할 때 np.argsort()를 이용한다. np.argsort()는 정렬 행렬의 원본 행렬 인덱스를 ndarray 형으로 반환한다.
argsort()는 넘파이의 데이터 추출에서 많이 사용되므로 주의 깊게 봐야한다.


▷선형대수 연산-행렬 내적(행렬 곱)
행렬 내적의 특성으로 왼쪽 행렬의 열 개수와 오른쪽 행렬의 행 개수가 동일해야 내적 연산이 가능하다.


▷선형대수 연산-전치 행렬
원 행렬에서 행과 열 위치를 교환한 원소로 구성한 행렬을 그 행렬의 전치 행렬이라고 한다.

numpy.ipynb
0.02MB

판다스
▷판다스의 주요 구성 요소-DataFrame, Series, Index


▷DataFrame과 리스트, 딕셔너리, 넘파이 ndarray 상호 변환


▷DataFrame의 컬럼 데이터 세트 생성과 수정
→ [ ]연산자를 이용해 쉽게 할 수 있다.
●DataFrame[ ] 내에 새로운 컬럼명을 입력하고 값을 할당해주기만 하면 된다.
ex1 ) titanic_df['Age_0'] = 0 을 하면 새로운 컬럼명 'Age_0'에 모든 데이터값이 0으로 할당된다.
ex2 ) titanic_df['Age_by_10'] = titanic_df['Age'] * 10 을 하면 새로운 컬럼명 'Age_by_10'에 기존 컬럼 'Age'에 10을 곱한 값들이 할당된다.
ex3 ) titanic_df['Family_No'] = titanic_df['SibSp'] + titanic_df['Parch'] + 1 도 마찬가지다.
●DataFrame 내의 기존 컬럼 값도 쉽게 일괄적으로 업데이트할 수 있다.
ex1 ) titanic_df['Age_by_10'] = titanic_df['Age_by_10'] + 100


▷(TIP). 파라미터 inplace
변수 갱신 여부를 설정하는 파라미터
(본인은 변수를 다시 정의하는 것보다 inplace를 사용하는게 편하더라)


▷DataFrame 데이터 삭제
DataFrame의 drop()
DataFrame.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise')
●axis: DataFrame의 로우를 삭제할 때는 axis=0, 컬럼을 삭제할 때는 axis=1로 설정(2차원 행렬에서 axis0은 로우 방향, axis1은 컬럼 방향: 'numpy ndarray axis 축 이해' 참고)
●로우를 삭제할 때는 labels에 index를 입력, 컬럼을 삭제할 때는 labels에 컬럼명을 입력
●여러개의 로우나 컬럼들의 삭제는 drop의 인자로 삭제 로우나 컬럼들을 리스트로 입력
●원본 DataFrame은 유지하고 드롭된 DataFrame을 새롭게 객체 변수로 받고 싶다면 inplace=False로 설정(디폴트 값이 False임)
ex ) titanic_drop_df = titanic_df.drop('Age_0', axis=1, inplace=False)
●원본 DataFrame에 드롭된 결과를 적용할 경우에는 inplace=True를 적용
ex ) titanic_df.drop('Age_0', axis=1, inplace=True)


▷판다스 Index 객체
●판다스의 Index 객체는 RDBMS의 PK(Primary Key)와 유사하게 DataFrame, Series의 레코드를 고유하게 식별하는 객체(하지만 판다스 Index는 별도의 컬럼값이 아니다)
●DataFrame/Series 객체는 Index 객체를 포함하지만 DataFrame/Series 객체에 연산 함수를 적용할 때 Index는 연산에서 제외된다. Index는 오직 식별용으로만 사용된다.
●DataFrame/Series에서 Index 객체만 추출하려면 DataFrame.index 또는 Series.index 속성을 통해 가능
●판다스 Index는 반드시 숫자형 값이 아니어도 되며, 고유한 값을 유지 할 수 있다면 문자형/Datetime도 상관 없음
●DataFrame 및 Series에 reset_index() 메서드를 수행하면 새롭게 인덱스를 연속 숫자 형으로 할당하며 기존 인덱스는 'index'라는 새로운 컬럼명으로 추가된다.
# reset_index(drop=False, inplace=False)
(TIP)'index'가 새로운 컬럼명으로 추가 안하려면 파라미터 drop=True를 사용함


▷DataFrame 인덱싱 및 슬라이싱
1. [ ]
데이터 프레임의 컬럼 선택:df[col_name] or df[col_name_list]
ex) df[’col1’] →Series 반환 / df[[’col1’]] →데이터 프레임 반환
즉, column name => Series / column name list => Data Frame
컬럼 필터링 용도로만 사용!!

2. loc[ ], iloc[ ]
→위치 기반 인덱싱:iloc / 명칭(레이블) 기반 기반 인덱싱:loc

iloc[0,1] = 3 / loc[0, 'PassengerID'] = 1
iloc[0,1] = 3 / loc[0, 'PassengerID'] = error발생

3. 불린 인덱싱(마스킹 검색)
조건식에 따른 필터링을 제공(조건이 여러개면 각 조건마다 괄호()를 씌움)
df[부울리스트] / df.loc[부울 리스트] : True인 요소의 위치에 대응되는 행만 가져옴
ex ) titanic_boolean = titanic_df[titanic_df['Age'] > 60] / titanic_boolean = titanic_df.loc[titanic_df['Age'] > 60]
→둘 중 입맛에 맞는거 사용
# 불린 인덱싱은 [ ], loc[ ]에서 공통으로 지원한다. iloc[ ]는 불린 인덱싱이 지원되지 않는다.
# and 조건: & / or 조건: | / not 조건: ~


▷DataFrame과 Series의 정렬-sort_values()
●DataFrame의 sort_values() 메소드는 by 인자로 정렬하고자 하는 컬럼값을 입력 받아서 해당 컬럼값으로 DataFrame을 정렬, 오름차순 정렬이 기본이며 ascending=True로 설정됨. 내림차순 정렬 시 ascending=False로 설정

마찬가지로, 여러 개의 컬럼으로 정렬하는 경우도 by 인자로 정렬하고자 하는 컬럼값들을 입력

●Series의 경우 컬럼 한 개에 대한 값이므로 by 인자를 사용할 필요가 없고, 오름차순/내림차순 정렬 기준만 설정하면 된다.
→Series.sort_values()


▷Aggregation 함수 적용
●sum(), max(), min(), count() 등은 DataFrame/Series에서 집합(Aggregation)연산을 수행
●DataFrame의 경우 DataFrame에서 바로 aggregation을 호출할 경우 모든 컬럼에 해당 aggregation을 적용
ex ) titanic_df.count()
●특정 컬럼에 aggregation을 적용하려면 컬럼 필터링 후 aggregation 적용
ex ) titanic_df[['Age','Fare']].mean()


▷groupby()적용
●DataFrame을 groupby 대상 컬럼을 기준으로 그룹화하는 함수
●사용 구조:df.groupby(groupby 대상 컬럼)[적용 기준 컬럼].집계함수
●주요 입력
- by: groupby 대상 컬럼
- as_index: groupby 대상 컬럼을 인덱스로 사용할 것인지 여부(default:True)

1. groupby 대상 컬럼을 제외한 모든 컬럼에 해당 aggregation 함수 적용
df.groupby('Pclass').count()
2. groupby에 특정 컬럼만 aggregation 함수 적용
df.groupby('Pclass')[['PassengerID', 'Survived']].count()
3. 서로 다른 aggregation 함수 적용
df.groupby('Pclass')['Age'].agg([max, min])
4. 여러 개의 컬럼이 서로 다른 aggregation 함수 적용(딕셔너리 형태로 aggregation이 적용될 컬럼들과 aggregation 함수를 입력)
agg_format = {'Age': 'max', 'SibSp': 'sum', 'Fare': 'mean'}
df.groupby('Pclass').agg(agg_format)

(TIP). groupby 대상 컬럼이 여러개이면 리스트에 여러개의 컬럼들을 넣고 입력(어떤 경우에 리스트로 만들고 안만들고 헷갈리니 컬럼이 한개일때도 리스트에 컬럼을 넣고 입력->groupby가 아닌 메소드일때도!!)
위에는 안한 경우임


▷결측 데이터 처리하기
●isna()로 결측 데이터 여부 확인
→isna().sum() 을 사용해 결측 데이터의 개수 확인
●fillna()로 결측 데이터 대체


▷nunique()
유니크한 값의 개수 반환
ex) df['Survived'].nunique()


▷replace()
원본 값을 특정값으로 대체
●한 개의 값만 대체할 경우
df['Sex'].replace('male', 'Man')
●여러개의 값을 대체할 경우 딕셔너리 사용
df['Sex'].replace({'male': 'Man', 'female': 'Woman'})
# 파라미터 inplace 활용



▷apply lambda 식으로 데이터 가공
●lambda 식 이해
lambda 식은 파이썬에서 함수형 프로그래밍을 지원하기 위해 만들어졌으며, 일반적으로 파이썬에서 함수를 만들 때 여러 줄의 코드를 찍지만 lambda식을 사용하면 한줄의 코드로 함수를 만들수 있다.

●Pandas는 apply lambda 식을 결합해 DataFrame이나 Series의 레코드별(행별)로 데이터를 가공하는 기능을 제공한다. 판다스의 경우 컬럼에 일괄적으로 데이터 가공을 하는 것이 속도 면에서 더 빠르나 복잡한 데이터 가공이 필요할 경우 어쩔 수 없이 apply lambda를 이용한다.

lambda 식을 이용할 때 여러 개의 값을 입력 인자로 사용해야 할 경우 map()함수를 결합해서 사용한다.

a = [1,2,3]
squares = map(lambda x : x**2, a)
list(squares)

lambda 식은 if, else만 지원하고 elif는 지원하지 않는다. if 절의 경우 if 식보다 반환 값을 먼저 기술해야 한다. 이는 lambda 식 ':' 기호의 오른편에 반환 값이 있어야 하기 때문이다.

elif를 이용하기 위해서는 else 절을 ()로 내포해 () 내에서 다시 if else 적용해 사용한다.

titanic_df['Age_cat'] = titanic_df['Age'].apply(lambda x : 'Child' if x<=15 else ('Adult' if x <= 60 else 
                                                                                  'Elderly'))

하지만 else if가 많이 나와야 하는 경우 이렇게 else를 계속 내포해서 쓰기 부담스럽다. 이 경우 아예 별도의 함수를 만들어 반환값으로 지정하는 것이 더 나을 수 있다.

def get_category(age):
    if age <= 5:
        cat = 'Baby'
    elif age <= 12:
        cat = 'Child'
    elif age <= 18:
        cat = 'Teenager'
    elif age <= 25:
        cat = 'Student'
    elif age <= 35:
        cat = 'Young Adult'
    elif age <= 60:
        cat = 'Adult'
    else:
        cat = 'Elderly'

    return cat

# lambda 식에 위에서 생성한 get_category( ) 함수를 반환값으로 지정. 
titanic_df['Age_cat'] = titanic_df['Age'].apply(lambda x : get_category(x))
titanic_df[['Age', 'Age_cat']].head()
pandas.ipynb
1.15MB

+ Recent posts