빅분기 준비 실전 예제 5

SeongGyun Hong·2024년 11월 23일

빅데이터 분석기사

목록 보기
12/16

1. 조건 필터링 .str 통한 문자열 접근

.str을 통해서 해당 칼럼 벨류에 문자열 접근 가능.

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(len(df))
print('0000')
# f4가 E로 시작하면서
target_E = df[df['f4'].str[0] == 'E']
print(len(target_E))
print('1111')
# 부산에 살고
target_bs = target_E[target_E['city'] == '부산']
print(target_bs)
print('2222')
# 20대인 사람은
target_age = target_bs[(target_bs['age'] < 30) & (target_bs['age'] >=20)]
print(target_age)
print('3333')
# 몇명인가
print(target_age)
# 엥 이거 왜 0명이냐... 아니 정답이 0이네...

2. str.contains()

.str로 접근한 후에 .contains를 사용하면 해당 문자열에서 특정 문자가 포함되는 경우를 필터링할 수 있다.

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform

df = pd.read_csv("/kaggle/input/bigdatacertificationkr/payment.csv")
print(df.head())
print('1111')

target = df[df['menu'].str.contains('라떼')]
print(target.count())
print('2222')

len은 NaN 포함 전체 행의 갯수를 세주고
.count()를 하면 각 칼럼마다 NaN을 제외한 행의 갯수를 세주니까
이거 두개 적절하게 비교해가면서 하면 좋을 듯.

3. apply(함수)

그런데 이번꺼는 문제가 좀...

바닐라라떼 5점, 카페라떼 3점, 아메리카노 2점, 나머지 0점이다 총 메뉴의 점수를 더한 값은?¶

이런 문제였는데
아니... 정답에 카페 라떼
이것도 들어가게 하면 안 되지 않나...?
'카페라떼' 랑 '카페 라떼'랑 다른거 아닌가..?
어쨌든... 만약 띄어쓰기같은 것도 전처리해줬어야 하는거면

df['menu'].str.replace(' ', '')

이렇게 해주고 했어야하긴 함...
아래는 그렇게 안하고 그냥 푼 풀이

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform

df = pd.read_csv("/kaggle/input/bigdatacertificationkr/payment.csv")
print(df.head(50))
def menu_score(x):
    if x == '바닐라라떼':
        return 5
    elif x == '카페라떼':
        return 3
    elif x == '아메리카노':
        return 2
    else:
        return 0

df['score'] = df['menu'].apply(menu_score)

print(df['score'])

4. 필터링

iloc 활용 잘하자! reset_index() 사용 잘 안할거면..

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform

df = pd.read_csv("/kaggle/input/bigdatacertificationkr/payment.csv")
print(df.head(10))
print('1111')
# hour, 13시 이전(13시 미포함) 데이터 중에서
target = df[df['hour'] < 13]

# 가장 많은 결제가 이루어진 날짜
answer = target.groupby('date').size().reset_index()
print(answer.sort_values(by = 0, ascending = False)['date'].iloc[0])
print('2222')

5. datetime format 맞추기

datetime foramt 관련 항상 %는 Y,y,m,d 앞에 오자...

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform

df = pd.read_csv("/kaggle/input/bigdatacertificationkr/payment.csv")
# print(df.head())
# print(df.info())
df['datetime'] = pd.to_datetime(df['date'], format = '%Y%m%d')
# print(df['datetime'])

target = df.groupby([df['datetime'].dt.month, 'date'])['price'].sum()
print(target)
# 12월 25일 = 9000

total_target = df[df['datetime'].dt.month == 12]['price'].sum()
print(int((9000 / total_target)*100))

6. flatten(), pd.melt()

그냥 원소단위로 다 뽑아서 np.array 만들고
이후에 flatten 해서 sort() 해도 된다.
아래처럼 풀어도 무방!

import pandas as pd
import numpy as np

df = pd.DataFrame({'Name': {0: '김딴짓', 1: '박분기', 2: '이퇴근'},
                   '수학': {0: 90, 1: 93, 2: 85},
                   '영어': {0: 92, 1: 84, 2: 86},
                   '국어': {0: 91, 1: 94, 2: 83},})

print(df.head())
print(df.columns)
print('1111')
target = df[['수학', '영어', '국어']]
print(target)
target = target.values
print(target)

answer = target.flatten()
print(answer)
answer = np.sort(answer)
print(np.sum(answer[-5:]))

그런데 pd.melt 라는 것도 있음.
이건 재구조화 시키는 느낌. pivot과 비슷하다고 해야하나..?

pd.melt라는걸 기억해뒀다가 나중에 help써서 봐도 된다!

import pandas as pd
import numpy as np

df = pd.DataFrame({'Name': {0: '김딴짓', 1: '박분기', 2: '이퇴근'},
                   '수학': {0: 90, 1: 93, 2: 85},
                   '영어': {0: 92, 1: 84, 2: 86},
                   '국어': {0: 91, 1: 94, 2: 83},})
print(df)

target = pd.melt(df, id_vars = ['Name'])
print(target)
answer = target.sort_values(by = 'value', ascending = False)
print(answer.value.iloc[:5].sum())

특정 칼럼에만 melt 하고 싶을때는
사전에 target 변수 설정해서 스코프를 줄이고 하면 된다.
그리고 melt 하고 나온 return 또한 dataframe이다.

import pandas as pd
import numpy as np

df = pd.DataFrame({'Name': {0: '김딴짓', 1: '박분기', 2: '이퇴근'},
                   '수학': {0: 90, 1: 93, 2: 85},
                   '영어': {0: 92, 1: 84, 2: 86},
                   '국어': {0: 91, 1: 94, 2: 83},})

print(df)

target = df[['수학', '영어']]
print(target)
answer = pd.melt(target)
print(answer)
answer = answer[answer['value'] >= 90]['value'].mean()
print(int(np.floor(answer)))

7. sigmoid의 적용

import pandas as pd
import numpy as np
from scipy.special import expit

df = pd.read_csv("../input/bigdatacertificationkr/basic1.csv")
print(df.head())
# f2 값에 시그모이드 적용
# f4가 ISFJ인 경우의 변경된 f2의 값 합을 구하라
# 소숫점 둘째자리까찌 출력, 반올림!
df['f2'] = df['f2'].apply(expit)
print(df.head())

target = df[(df['f4'] == 'ISFJ')]['f2'].sum()
print(round(target, 2))

이외에도 numpy로 구현할 수도 있다.
아래는 시그모이드 구현

import numpy as np

def sigmoid(x):
	return 1/(1 +np.exp(-x))

아래는 렐루 구현

import numpy as np

def relu(x):
	return np.maximum(0, x)

8. pd.Timedelta 에 접근할 수 있는 것

pd.datetime 객체 끼리 연산 하고 나면
pd.Timedelta 객체들로 남을텐데

여기에 아래와 같이 total_seconds()로 접근하면 절대적인 총량을 알 수 있다.

df['delta'].dt.total_seconds()

이렇게 계산해주고 나면 /60 하면 이 된다.

import pandas as pd
import numpy as np


# 0
df = pd.read_csv("/kaggle/input/bigdatacertificationkr/website.csv")
print(df.head(3))


# 1. 세션 지속시간 분으로 계산 후 / 가장 긴 지속시간 출력 (반올림 후 총 분만 출력)
df['StartTime'] = pd.to_datetime(df['StartTime'])
df['EndTime'] = pd.to_datetime(df['EndTime'])
df['total_seconds'] = df['EndTime'] - df['StartTime']
df['total_minutes'] = df['total_seconds'].dt.total_seconds() / 60
target_1 = df.total_minutes.max()
answer_1 = int(round(target_1, 0))
print(answer_1)


# 2. 가장 많이 머무른 Page 찾고 / 그 페이지에서 머문 평균 시간 구하라  (반올림 후 총 시간만 출력)
target_2 = df.groupby(['Page'])['total_seconds'].sum()
print(target_2)
session_mean = df[df['Page'] == "Page5"]['total_seconds'].mean()
print(session_mean / 60)


# 3. 구간 나누기 각 구간별 가장 많이 시작된 세션 수를 계산하고, 그중 가장 많은 세션 수 출력
def div_session(x):
    if (x >= 0) and (x < 6):
        return "새벽"
    elif (x >= 6) and (x < 12):
        return "오전"
    elif (x >= 12) and (x < 18):
        return "오후"
    else:
        return "저녁"
df['StartHour'] = df['StartTime'].dt.hour
df['div_session'] = df['StartHour'].apply(div_session)
target_3 = df.groupby('div_session').size().reset_index().sort_values(by = 0)
print(target_3)
answer_3 = target_3.iloc[-1, -1]
print(answer_3)


# 4. user가 가장 많이 접속했던 날짜는?
df['login'] = df['StartTime'].dt.to_period('D')
target_4 = df.groupby('login').size().sort_values(ascending = False).reset_index()
print(target_4)
answer_4 = target_4.iloc[0,0]
print(answer_4)

또 다른 응용문제

import pandas as pd
import numpy as np

df = pd.read_csv("/kaggle/input/bigdatacertificationkr/e-commerce.csv")
print(df.head())
print(df.info())
print('0000')

df['str_length'] = df['Feedback'].str.len()
target_1 = df.sort_values(by = 'str_length', ascending = False).reset_index()
answer_temp = target_1['UserID'].iloc[0] # 8
answer_1 = sum(df['UserID'] == 8)
print(answer_1)
print('1111')

df['contain'] = df['Feedback'].str.contains('제품')
df['OrderDate'] = pd.to_datetime(df['OrderDate'])
df['ArrivalDate'] = pd.to_datetime(df['ArrivalDate'])
df['time'] = (df['ArrivalDate'] - df['OrderDate']).dt.total_seconds()

target_2 = df.groupby('Category')['contain'].size().sort_values(ascending = False)
print(target_2) # 서비스

answer_2 = df[df['Category'] == '서비스']['time'].mean()
answer_2 = round(answer_2 / 60, 2)
print(answer_2)

profile
헤매는 만큼 자기 땅이다.

0개의 댓글