빅분기 준비 실전 예제 4

SeongGyun Hong·2024년 11월 22일

빅데이터 분석기사

목록 보기
11/16

1. 데이터프레임에서의 연산

연산자/메서드역할반환값 형식메서드 이름결측값 처리 옵션
/나눗셈 (소수점 포함)부동소수점(float)DataFrame.div()fill_value
//몫 연산 (소수점 버림)정수(int) 또는 floatDataFrame.floordiv()fill_value
%나머지 연산정수(int) 또는 floatDataFrame.mod()fill_value
  • /, //, %는 요소별(element-wise)로 계산.
  • 메서드(div, floordiv, mod)는 결측값 처리(fill_value) 옵션 제공.

2. 구간분할

먼저 내 풀이는 살짝 노가다 였는데 아래로 풀어도 되긴 한다.

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())

3. 주단위 정렬

핵심적이게 사용되는 것은 바로 아래
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)

4. 중복제거

아 ;;;
df.drop_duplicates임을 반드시 명심하자...
s 안 붙혀서 10분 날림 ;; 아 ;;

그리고 중요한거 하나 ;;
iloc 이거 잘 써먹자.
아래와 같이 결과를 완전 다르게 만들어 준다...
제대로 정수 인덱싱으로 해서 써먹자...

iloc로 인덱싱 하는 경우

f1_fill = df['f1'].sort_values(ascending=False).iloc[9]
  • iloc: 정렬된 시리즈에서 정수 위치 기반 인덱싱을 사용한다.
  • 즉, 정렬된 결과에서 9번째 위치에 있는 값을 반환하는 것

그냥 인덱스 번호로 []추출하는 경우

f1_fill = df['f1'].sort_values(ascending=False)[9]
  • ``: 정렬된 시리즈에서 원래의 인덱스 값이 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() 쓰는 것도 뭐 나쁘지 않다. 인덱싱 실수하는 것 보다야 뭐...

5. fillna(method = ?), shift(?)

결측치를 채우는 방법이 참 많은데
그 중에 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)
profile
헤매는 만큼 자기 땅이다.

0개의 댓글