| 연산자/메서드 | 역할 | 반환값 형식 | 메서드 이름 | 결측값 처리 옵션 |
|---|---|---|---|---|
/ | 나눗셈 (소수점 포함) | 부동소수점(float) | DataFrame.div() | fill_value |
// | 몫 연산 (소수점 버림) | 정수(int) 또는 float | DataFrame.floordiv() | fill_value |
% | 나머지 연산 | 정수(int) 또는 float | DataFrame.mod() | fill_value |
/, //, %는 요소별(element-wise)로 계산.div, floordiv, mod)는 결측값 처리(fill_value) 옵션 제공.먼저 내 풀이는 살짝 노가다 였는데 아래로 풀어도 되긴 한다.
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform
df = pd.read_csv('../input/bigdatacertificationkr/basic1.csv')
print('시작')
# 틀린 풀이. '이창치' 라고 했지 '결측치' 라고 안 했다.
# df = df.dropna(subset = ['age'])
df = df[(df['age'] > 0) & ((df['age'] % 1.0 ) == 0.0)][['age']].sort_values(by = 'age')
print(df.head())
print('1111')
group_1 = df[0:30].median()
group_2 = df[30:60].median()
group_3 = df[60:91].median()
print(group_1 + group_2 + group_3)
그런데 좀 더 깔끔하게 풀기위해서는 qcut을 쓰는 것이 좋다.
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform
df = pd.read_csv('../input/bigdatacertificationkr/basic1.csv')
df = df[(df['age'] > 0) & ((df['age'] % 1.0) == 0)]
df['group'] = pd.qcut(df['age'], q = 3, labels = ['num_1', 'num_2', 'num_3'])
target = df.groupby('group')['age'].median().reset_index()
print(target)
print(target.age.sum())
핵심적이게 사용되는 것은 바로 아래
df['Date'].dt.to_period('W')가 되겠다.
그런데 위와 같은 to_period 방법 외에도
시계열 데이터에 대하여
df.resample('W')와 같은 식으로 그룹화도 가능한데,
이렇게 하면 놀랍게도 2주단위로 2W 같은 것도 인자로 넣을 수도 있다;;
월단위는 M!
바로 아래는 to_period로 푼 방식
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform
df = pd.read_csv("../input/bigdatacertificationkr/basic2.csv")
print(df.head())
print(df.info())
df['Date'] = pd.to_datetime(df['Date'])
target = df.groupby(df['Date'].dt.to_period('W'))['Sales'].sum().reset_index()
print(target)
print('1111')
answer = target['Sales']
print(abs(answer.max() - answer.min()))
아래는 df.resample('W')로 푼 방식
다만 따로 인덱스 명을 설정해줄 게 아니라면
꼭 쓸때마다 on으로 기준 삼을 시계열 칼럼명을 기입해주자!
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform
df = pd.read_csv("../input/bigdatacertificationkr/basic2.csv")
print(df.head())
print(df.info())
df['Date'] = pd.to_datetime(df['Date'])
target = df.resample('W', on = 'Date').sum()
answer_max = target.max()
answer_min = target.min()
answer = answer_max - answer_min
print(answer)
아 ;;;
df.drop_duplicates임을 반드시 명심하자...
s 안 붙혀서 10분 날림 ;; 아 ;;
그리고 중요한거 하나 ;;
iloc 이거 잘 써먹자.
아래와 같이 결과를 완전 다르게 만들어 준다...
제대로 정수 인덱싱으로 해서 써먹자...
f1_fill = df['f1'].sort_values(ascending=False).iloc[9]
iloc: 정렬된 시리즈에서 정수 위치 기반 인덱싱을 사용한다.f1_fill = df['f1'].sort_values(ascending=False)[9]
| 표현 | 동작 방식 | 반환 기준 |
|---|---|---|
iloc | 정렬된 시리즈에서 정수 위치로 접근 | 정렬된 결과의 9번째 값 |
| `` | 정렬된 시리즈에서 원래 인덱스 9로 접근 | 원래 인덱스가 9인 값 |
import pandas as pd
# 샘플 데이터프레임 생성
data = {'f1': [5, 1, 8, 3, 2, 9, 4, 7, 6, 0]}
df = pd.DataFrame(data)
# 첫 번째 방법: iloc 사용
f1_fill_iloc = df['f1'].sort_values(ascending=False).iloc[9]
# 두 번째 방법: 직접 인덱싱
f1_fill_direct = df['f1'].sort_values(ascending=False)[9]
print("iloc[9]:", f1_fill_iloc)
print("[9]:", f1_fill_direct)
iloc[9]: 0
[9]: 4
iloc: 정렬된 결과에서 9번째 값인 0을 반환.: 원래 인덱스가 9인 값인 4`를 반환.두 표현은 비슷해 보이지만 동작 방식이 르다
iloc: 정렬된 데이터의 순서를 기준으로 값을 가져오고[]: 원래 인덱스를 기준으로 값을 가져온다.따라서 의도한 바가 정수인덱싱으로 순서를 따라 뽑는거라면 iloc를 사용해야 한다...
이거 잘 모르겠으면 매번 그냥 reset_index() 생활화 하자...
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform
df = pd.read_csv('../input/bigdatacertificationkr/basic1.csv')
print(df.head())
print(df.info())
print('1111')
f1_fill = df['f1'].sort_values(ascending = False).reset_index()['f1'][9]
print(f1_fill)
print('2222')
df['f1'] = df['f1'].fillna(f1_fill)
target_drop = df.drop_duplicates(subset = 'age', keep = 'first')['f1'].median()
target_no_drop = df['f1'].median()
answer = target_drop - target_no_drop
print(abs(answer))
이렇게 풀던가
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform
df = pd.read_csv('../input/bigdatacertificationkr/basic1.csv')
print(df.head())
print(df.info())
print('1111')
f1_fill = df['f1'].sort_values(ascending = False).iloc[9]
print(f1_fill)
print('2222')
df['f1'] = df['f1'].fillna(f1_fill)
target_drop = df.drop_duplicates(subset = 'age', keep = 'first')['f1'].median()
target_no_drop = df['f1'].median()
answer = target_drop - target_no_drop
print(abs(answer))
이렇게 풀던가...
reset_index() 쓰는 것도 뭐 나쁘지 않다. 인덱싱 실수하는 것 보다야 뭐...
결측치를 채우는 방법이 참 많은데
그 중에 fillna 안에 들어가는 method에 해당하는 인자로도 채울 수 있다.
fillna(method = 'bfill') 바로 뒤의 값으로 (1번행은 2번행 값으로 채운다) 채우고
fillna(method = 'ffill')의 경우 바로 앞의 값으로 (2번행은 1번행 값으로 채운다) 채운다.
shift(1)
이게 무엇인고 하니,,,
데이터를 위/아래(행) [axis=0] 또는 왼쪽/오른쪽(열) [axis =1]으로 이동시키는 것으로, 이동된 위치에는 원래 값이 없어지므로, 결측값(NaN, NaT)이 채워지게 됨.
기본적으로는 행(axis=0) 방향으로 작동함.
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform
df = pd.read_csv("../input/bigdatacertificationkr/basic2.csv")
print(df.head())
print(df.info())
df['Date'] = pd.to_datetime(df['Date'])
# 아... shift(1) 라는 것도 있구나...
df['pv'] = df['PV'].shift(1)
print(df.head())
print('1111')
df['pv'][0] = df['pv'][1]
target = df[(df['Events'] == 1) & (df['Sales'] <= 1000000)]
answer = target.pv.sum()
print(answer)