빅분기 준비 실전 예제 3

SeongGyun Hong·2024년 11월 22일

빅데이터 분석기사

목록 보기
10/16

다시한번 감사합니다... 감사합니다...

1. 상관관계: corr(), loc, iloc, max, min

print(type(df.corr()))
이렇게 해보면 알겠지만
출력은 언제나 dataframe이다.
<class 'pandas.core.frame.DataFrame'>
그래서 이걸 통해 알 수 있뜻이 특정 칼럼으로 접근이 가능.

target = df.corr().reset_index()
위와 같이 reset_index()를 해주면
index 였던 column_name들이 첫번째 칼럼의 value들로 다 들어오는데

이렇게 접근해서

target = df.corr().reset_index()

print(target)

print('---')
answer = target[target['index'] == 'quality']

print(answer)

이렇게 직접 보고 풀어도 되지만
아래처럼 그냥 iloc로 접근해서 어차피 corr의 경우에는 마지막 칼럼에 자기 자신에 대한 칼럼이 나오므로 제외하고 구해도 괜찮다.

# 데이터 불러오기
df = pd.read_csv("../input/red-wine-quality-cortez-et-al-2009/winequality-red.csv")

# print(df.head())

target = df.corr()

target = target.iloc[:-1, -1]

print('----')
print(target)

cor_max = abs(target).max()
cor_min = abs(target).min()

answer = round(cor_max + cor_min, 2)

print(answer)

2. groupby, sort_values(by), reset_index, sum

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import power_transform
print('시작')
df = pd.read_csv("../input/bigdatacertificationkr/basic1.csv")


print(df.head())
print('----')
print(df.info())

target = df.groupby(['city', 'f4'])['f5'].mean().reset_index()
answer = target.sort_values(by = 'f5', ascending = False).head(7)
print(round(answer['f5'].sum(),2))

3. 슬라이싱, 조건 처리

import pandas as pd
import numpy as np
print('시작')
# 데이터 불러오기
df = pd.read_csv("../input/bigdatacertificationkr/basic1.csv")

df = df.sort_values(by = 'age', ascending = False).head(20)
print(df.head())
print('--1--')

df['f1'] = df['f1'].fillna(df['f1'].median())
print(df['f1'])
print('--2--')

target = df[(df['f4'] == 'ISFJ') & (df['f5'] >= 20)]

print(target)
print('--3--')

answer = target['f1'].mean()

print(answer)
print('--4--')

4. 분산, 오름차순, 내림차순

오름차순: ascending = True : 기본값
내림차순: ascending = False : 설정값

import pandas as pd
import numpy as np

# 데이터 불러오기
df = pd.read_csv("../input/bigdatacertificationkr/basic1.csv")

print(df.head())
print('111111')

target = df[df['f2'] == 0].sort_values(by = 'age', ascending = True).head(20)
print(target)
print('222222')

target['f1_full'] = target['f1'].fillna(target['f1'].min())
answer_1 = target['f1_full'].var()
print(answer_1)
print('333333-1')

answer_2 = target['f1'].var()
print(answer_2)
print('333333-2')

answer = round(answer_2 - answer_1, 2)
print(answer)
print('last')

5. Datetime

5.1 Datetime: df['Date'].dt.to_period('M')

pd.to_datetime()
df['Date'].dt.to_period('M') == pd.to_datetime("2022-05").to_period('M')
pd.Timedleta

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

print(df.info())
print('2222')

df['Date'] = pd.to_datetime(df['Date'])
print(df.info())
print('3333')

target = df[df['Date'].dt.to_period('M') == pd.to_datetime("2022-05").to_period('M')]
answer = target['Sales'].median()
print(answer)
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform

df = pd.read_csv("../input/bigdatacertificationkr/basic2.csv")

df['Date'] = pd.to_datetime(df['Date'])
target = df[(df['Date'].dt.month == 5) & (df['Date'].dt.year == 2022)]
answer = target['Sales'].median()
print(answer)

5.2 Datetime: df['Date'].dt.weekday

df['Date'].dt.weekday
pd.to_datetime으로 datetime 벨류를 갖게된 시리즈에
.weekday를 붙여주게되면
월요일은 0, 화요일은 1 이런식으로 일요일 6까지 넘버링해서
시리즈로 뱉어낸다.
이걸 이용하면 요일로도 추출할 수 있다.

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'])

df = df[df['Date'].dt.to_period('M') == pd.to_datetime("2022-05").to_period('M')]

df['weekday'] = df['Date'].dt.weekday


target_day = df[df['weekday'] <= 4]
target_end = df[df['weekday'] >= 5]

answer_day = target_day.Sales.mean()
answer_end = target_end.Sales.mean()

answer = round(abs(answer_day - answer_end),2)
print(answer)
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, power_transform

df = pd.read_csv("../input/bigdatacertificationkr/basic2.csv")

df['Date'] = pd.to_datetime(df['Date'])

target = df[(df['Date'].dt.year == 2022) &(df['Date'].dt.month == 5)]
print(target.head())
print('1111')
target['weekday'] = target['Date'].dt.weekday
print(target.head())
print('2222')
answer_day = target[target['weekday'] <= 4].Sales.mean()
answer_week = target[target['weekday'] >= 5].Sales.mean()

print(round(abs(answer_day - answer_week),2))

5.3 Datetime 활용 필터링시 주의사항

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

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

df['Date'] = pd.to_datetime(df['Date'])

df['Sales'] = df[df['Events'] == 1]['Sales'] * 0.8

target = df.groupby(df['Date'].dt.to_period('M'))['Sales'].sum().reset_index()
print(target)
print('2222')

target_2022 = target[target['Date'].dt.year == 2022]
target_2023 = target[target['Date'].dt.year == 2023]

target_2022_max = target_2022['Sales'].max()
target_2023_max = target_2023['Sales'].max()

answer = round(abs(target_2022_max - target_2023_max),0)
print(answer)

위 코드에서 df['Sales'] = df[df['Events'] == 1]['Sales'] * 0.8
이렇게 필터링을 해버리면
미충족 행을 NaN이 들어가 버린다 ;;
따라서 이럴 경우 lambda를 이용해 접근하는 것이 일반적.

또한 lambda 쓰면서 주의할 것이 바로 axis 인자인데

  • axis=0 → 행(index)을 따라 계산하고, 결과는 열(column)별로 나옴.
    "세로 축을 기준으로 동작"
  • axis=1 → 열(columns)을 따라 계산하고, 결과는 행(row)별로 나옴.
    "가로 축을 기준으로 동작"
import pandas as pd
import numpy as np
from sklearn.preprocessing import power_transform, MinMaxScaler

df= pd.read_csv("../input/bigdatacertificationkr/basic2.csv")

print(df.head())

df['Date'] = pd.to_datetime(df['Date'])

df.loc[df['Events'] == 1, 'Sales'] = df['Sales']*0.8

target = df.groupby(df['Date'].dt.to_period('M'))['Sales'].sum().reset_index()
print(target)

re_target = target.groupby(target['Date'].dt.year)['Sales'].max().reset_index()
print(re_target)

answer_2022 = re_target['Sales'][0]
answer_2023 = re_target['Sales'][1]

answer = abs(answer_2022 - answer_2023)

print(round(answer, 0))

이렇게 groupbydf.loc로 스코프를 줄여나가는 방법이 있고

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

df= pd.read_csv("../input/bigdatacertificationkr/basic2.csv")

print(df.head())

df['Date'] = pd.to_datetime(df['Date'])

df['Sales'] = df.apply(lambda x: x['Sales']*0.8 if x['Events'] == 1 else x['Sales'], axis = 1)

target = df.groupby(df['Date'].dt.to_period('M'))['Sales'].sum().reset_index()
re_target = target.groupby(target['Date'].dt.year)['Sales'].max().reset_index()
print(re_target)

answer = re_target['Sales'][1] - re_target['Sales'][0]

print(int(round(answer, 0)))

이렇게 apply이용해서 스코프 줄여나가는 방안도 있다.

6. merge와 concat

mergeconcat은 데이터프레임을 병합하거나 결합할 때 사용하는 함수이지만, 동작 방식과 목적이 다르다.


6.1 merge

  • 주요 목적: 두 데이터프레임을 공통 키(key)를 기준으로 병합(조인)한다.
  • 동작 방식: SQL의 JOIN 연산과 유사하게, 공통된 컬럼(키)을 기준으로 데이터를 결합.
  • 사용 예시: 두 데이터프레임에 공통된 컬럼이 있을 때, 이를 기준으로 데이터를 연결하고 싶을 때 사용한다.

예제

import pandas as pd

# 데이터프레임 생성
df1 = pd.DataFrame({'id': [1, 2, 3], 'value1': ['A', 'B', 'C']})
df2 = pd.DataFrame({'id': [2, 3, 4], 'value2': ['X', 'Y', 'Z']})

# merge 사용
result = pd.merge(df1, df2, on='id', how='inner')  # 공통 컬럼 'id' 기준 병합
# how는 default가 inner이고 칼럼은 공통 칼럼 자동으로 설정되는 것이 default
print(result)

출력:

   id value1 value2
0   2      B      X
1   3      C      Y
  • on='id': id 컬럼을 기준으로 병합.
  • how='inner': 공통된 id 값(2, 3)만 포함.

merge의 주요 옵션

  • on: 병합할 때 사용할 공통 키(컬럼).
  • how: 병합 방식 (SQL JOIN처럼 작동).
    • 'inner': 교집합 (기본값).
    • 'outer': 합집합.
    • 'left': 왼쪽 데이터프레임 기준.
    • 'right': 오른쪽 데이터프레임 기준.

6.2 concat

  • 주요 목적: 여러 데이터프레임을 단순히 연결
  • 동작 방식: 행(row) 또는 열(column)을 기준으로 데이터를 이어붙임.
  • 사용 예시: 데이터프레임을 위아래로 쌓거나 좌우로 붙이고 싶을 때 사용.
  • 주의할 것은 병합이 아니라 진짜 말 그대로 이어 붙이는 거라서 칼럼 이름이 같다고 해서 중복되지 않음.
  • axis = 1로 하면 칼럼새로 생기면서 옆으로 붙고
  • axis = 0 으로 하면 (기본) 행으로 추가 됨. NaN 붙여서라도 있는 칼럼이면 있는 칼럼쓰고 없는 칼럼이면 NaN으로 채워서 생성함.

예제 (세로로 결합)

import pandas as pd

# 데이터프레임 생성
df1 = pd.DataFrame({'id': [1, 2], 'value': ['A', 'B']})
df2 = pd.DataFrame({'id': [3, 4], 'value': ['C', 'D']})

# concat 사용 (세로 결합)
result = pd.concat([df1, df2])
print(result)

출력:

   id value
0   1     A
1   2     B
0   3     C
1   4     D
  • 기본적으로 세로 방향(axis=0)으로 결합하여 행(row)이 추가됩니다.

예제 (가로로 결합)

# concat 사용 (가로 결합)
result = pd.concat([df1, df2], axis=1)
print(result)

출력:

    id value   id value
0    1     A    3     C
1    2     B    4     D
  • axis=1: 가로 방향으로 결합하여 열(column)이 추가됩니다.

concat의 주요 옵션

  • axis: 결합 방향.
    • axis=0: 세로 방향(행 추가, 기본값).
    • axis=1: 가로 방향(열 추가).
  • ignore_index: 인덱스를 새롭게 설정할지 여부.
  • keys: 계층적 인덱스를 생성하기 위해 사용.

6.3 비교 정리

특성mergeconcat
주요 목적공통 키를 기준으로 병합단순히 데이터를 위아래 또는 좌우로 연결
기준 컬럼 필요 여부필요 (on, 또는 공통 컬럼 자동 인식)필요 없음
결합 방향SQL JOIN처럼 동작 (행 중심)행(axis=0) 또는 열(axis=1) 중심
결과 크기 변화공통 키 값에 따라 달라짐단순히 행 또는 열 수가 늘어남
사용 사례관계형 데이터베이스처럼 데이터를 병합할 때여러 데이터프레임을 단순히 쌓고 싶을 때

결론

  • merge는 공통 키를 기준으로 데이터를 병합하는 데 적합하며, SQL의 JOIN 연산과 유사함.
  • concat은 단순히 데이터를 위아래(행 추가) 또는 좌우(열 추가)로 연결하는 데 적합함.

문제에서 두 데이터프레임을 특정 컬럼(ex.f4)을 기준으로 병합하라고 한다면 merge를 사용해야 한다.

문제풀이

결측치 제거
dropna 는 아는데
특정 칼럼에 해당하는 결측치만 제거할 수도 있다.
dropna(subset = ['칼럼이름']) 안에 꼭 리스트로 넘길것

import pandas as pd
import numpy as np


b1 = pd.read_csv("../input/bigdatacertificationkr/basic1.csv")
b3 = pd.read_csv("../input/bigdatacertificationkr/basic3.csv")

#print(b1.head())
#print(b3.head())

# basic 1의 f4 라고 했으니까... 왼쪽에 두고 left 주고 f4 칼럼으로 설정...
target = pd.merge(b1, b3, how = "left", on = 'f4')
print(target)
print('1111')

target = target.dropna(subset = ['r2'])

answer = target.head(20)['f2'].sum()

print(answer)
profile
헤매는 만큼 자기 땅이다.

0개의 댓글