[python] numpy, pandas, sklearn
NumPy
- 그냥 python for 돌면 무조건 느리다. C가 아니니까... 파이썬으로 아무리 해봐야 크게 개선이 안됨.
- 그래서 Pandas나 Numpy가 제공하는 방법 대로 접근하는게 제일 효과적인 성능 개선 방법.
```python
import numpy as np
x = np.array([1, 2, 3])
print(type(x))
> <class 'numpy.ndarray'>
```
특정 값을 가진 index들을 반환받는 방법 : where
산술 연산과 브로드캐스트
넘파이 배열에 대한 산술 연산자의 동작은 파이썬 기본 리스트와 다르다.
* 연산
```python
print(x*2) - 넘파이 배열 * 2
> [2 4 6]
l = [1, 2, 3]
print(l*2) - 파이썬 기본 리스트 * 2
> [1, 2, 3, 1, 2, 3]
```
+ 연산
```python
print(x+1)
> [2 3 4]
print(x + [3, 3, 3])
> [4 5 6]
파이썬 기본 리스트에 배열이 아닌 스칼라값(수치 하나)을 더할 수는 없다.
print(l + [3, 3, 3])
> [1, 2, 3, 3, 3, 3]
[3, 3] 같이 원소 수가 다른 배열을 더하면 넘파이는 오류,
파이썬 기본 리스트는 끝에 [3, 3]이 추가된다.
```
파이썬 리스트가 지원하는 연산자는 `` *, +`` 뿐이라 `` -, /``는 사용할 수 없다.
넘파이는 모든 연산자를 지원하며 원소별(element-wise) 연산을 수행한다.
넘파이 배열을 스칼라값과 산술 연산 하는 경우 넘파이 배열의 원소별로 한 번씩 계산이 수행된다. 이 기능을 브로드캐스트라고 한다.
브로드캐스트는 유용한 기능이지만 배열의 형상, 차원 순서를 주의깊게 맞춰주지 않으면 에러가 발생하기 쉽다.
또는 에러가 발생하지 않고 그냥 진행되어 이상하게 동작하거나.
리스트로 원소 선택하기 ( 인덱스로 리스트 넘기기 )
map
N차원 배열
파이썬 리스트와 같은 방법으로 작성한다.
행렬의 형상은 shape으로, 행렬에 담긴 원소의 자료형은 dtype으로 알아낼 수 있다.
행렬의 차수는 np.ndim()으로 알 수 있다.
```python
x = np.array([[1, 2], [4, 5]])
print(x.shape)
> (2, 2)
print(x.dtype)
> int32
print(x.ndim())
> 2
```
차원이 서로 다른(형상이 다른) 넘파이 배열 간의 산술 연산 시에도 브로드캐스트가 작동한다.
x[a, b]는 x[a][b]와 같다. 그러나 x[:a, :b]는 x[:a][:b]와 다르다.
```python
print(x[0, 1])
> 2
print(x[0][1])
> 2
```
flatten() 를 이용해 1차원 배열로 변경할 수 있다. 이를 평탄화 라고 부른다.
```python
x = x.flatten()
print(x)
> [1 2 4 5]
```
reshape() 를 이용해 형상을 변경할 수 있다.
```python
x = np.array([[1, 2, 3], [4, 5, 6]])
print(x.reshape(3, 2))
> [[1 2]
[3 4]
[5 6]]
print(x.reshape(x.size, -1)) #-1을 넣으면 알아서 나머지 크기만큼 묶어준다
> [[1]
[2]
[3]
[4]
[5]
[6]]
print(x = x.reshape(2, -1))
> [[1 2 3]
[4 5 6]]
```
transpose() 를 사용해 다차원 배열의 차원 순서를 변경할 수 있다.
선형대수에서 말하는 ^T 변환은 보통 .T를 사용한다.
단, `` .T``는 1차원 배열에는 동작하지 않는다! ``py [[1, 2, 3]]`` 이런 식으로 두 번 이상 묶어야 동작한다.
`` .reshape()``는 1차원 배열에도 동작한다.
```python
print(x.T)
> [[1 4]
[2 5]
[3 6]]
x = np.ones((1,2,3)) #형상이 (1, 2, 3)인 행렬 생성
print(x.shape)
> (1, 2, 3)
print(x.transpose(2, 0, 1).shape)
> (3, 1, 2)
```
행렬곱
Note ) 3.5 버전부터 자체적으로 행렬곱 연산자 ``python @``를 지원한다.
numpy.nditer 다차원 배열 순회
초기화 및 선언
shape이 분명 2차원이어야 하는데 (11351,) 과 같이 나올 때 해결방법
- 예를 들어 pandas Series의 원소가 리스트일 때 이런 문제를 마주치게 된다.
- https://stackoverflow.com/questions/50971123/converty-numpy-array-of-arrays-to-2d-array
- np.stack()을 사용하면 예상하는 shape (11351, 3) 으로 변환해준다.
Pandas
- Group by: split-apply-combine
- https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html
- Series에는 map이 있으나 DataFrame에는 map이 없다. 대신 apply가 있다.
- apply는 기본적으로 한 열 마다 적용되지만, axis 지정으로 한 행 마다 적용으로 바꿀 수 있다.
- 그래서 dataframe에서 한 행 을 가져와 여러 속성을 이용해 람다를 적용 하고 싶은 경우 axis=1 apply,
- 단순히 한 행에 람다를 적용하고 싶은 경우 Series.map 을 사용.
- transform은 한 열마다 적용 되는 것이므로, 두 개의 열을 묶어서 transform으로 넘기는 것은 불가능하다. (애초에 이런 경우 apply를 쓰는 것이 맞다)
```py
# 이런게 가능.
id_interval = csv['Timestamp'] - csv.groupby('Arbitration_ID')['Timestamp'].shift(1)
result['IdInterval'] = id_interval.fillna(-1)
```
MultiIndex
실세계의 많은 데이터가 MultiIndex 형태다. (학교 -> 학과 -> 학번)
https://data-make.tistory.com/126
```py
train_x_df = pd.read_csv(DATA_DIR + "train_x_df.csv", index_col=['coin_index', 'sample_id', 'time'])
# read_csv 말고도 다양한 방법으로 MultiIndex df로 만들 수 있음.
# (coin_index, sample_id) 별로, time을 1차원으로 쭉 붙이는 식으로 가공하려면
train_x_df.unstack()
# 컬럼 이름이 중복되는 것 끼리 열 단위 MultiIndex를 추가로 생성해서 묶어줌
```
https://pandas.pydata.org/docs/user_guide/reshaping.html#reshaping-by-stacking-and-unstacking
scikit-learn
차원 축소 ( dimension reduction ) : PCA
data_df_reducted = pd.DataFrame(data=pca.transform(test_data_df))
```
KernelPCA
LDA
'Languages & Frameworks > Python' 카테고리의 다른 글
[python] 출력 관련 : 문자열, str <> bytes, bytearray (2) | 2017.05.09 |
---|---|
[python] Jupyter notebook (2) | 2017.04.16 |
[python] url parsing / BeautifulSoup4, bs4 (0) | 2017.03.02 |
[python] argparse, python-fire (0) | 2017.02.26 |
[python] 파일 배포, python with C (0) | 2017.02.26 |