728x90
728x90
제1유형 시험 준비
들어가며
- 빅데이터분석기사 실기 제1유형 시험 준비를 위한 내용을 정리해본다.
- 제1유형은 데이터 전처리와 관련된 내용이 포함된다.
- 제2회 ~ 제8회 기출 변형 문제와 풀이 방법을 함께 정리하였다.
문제
📎 문제1 (21년 2회)
- BostonHousing 데이터
- @crim@ 항목의 상위에서 10번째 값(상위 10개의 값 중에서 가장 작은 값)으로 상위 10개의 값을 변환하고, @age@가 80 이상인 값에 대하여 @crim@의 평균 구하기
- 소수점 셋째 자리에서 반올림해서 소수점 둘째 자리로 출력하기
import numpy as np
import pandas as pd
df = pd.read_csv('./datasets/data_q1.csv')
# 'crim' 항목의 상위 10번째 값 뽑기
top10_value = df['crim'].nlargest(10).iloc[-1]
# 상위 10개의 값을 변환하기
df['crim'] = np.where(df['crim'] >= top10_value, top10_value, df['crim'])
# 'age'가 80 이상인 값에 대해 'crim'의 평균 구하기
answer = round(df.loc[df['age'] >= 80, 'crim'].mean(), 2)
print(answer)
📌 상위 n번째 값 뽑기 : @nlargest(n)@
- @nlargest(n)@ 함수는 자동으로 값을 내림차순으로 정렬하여 상위 n개의 값을 반환한다.
- @ nlargest@를 사용할 경우, @sort_values()@ 함수 등을 이용하여 따로 정렬 작업을 해주지 않아도 된다.
Series.nlargest(n, keep='first')
⇒ @n@ : 상위 n개의 값을 반환
⇒ @keep@ : 동일한 값이 여러 개 있을 때의 반환 방식
☑️ @first@ : 처음 등장한 값을 우선으로 선택 (기본값)
☑️ @last@ : 마지막으로 등장한 값을 우선으로 선택
☑️ @all@ : 중복된 값을 모두 포함
- 상위에서 @n@번째 값을 뽑고자 할 경우, 다음과 같이 코드를 작성한다.
topN_value = topN.iloc[-1] # 마지막 행 값 선택
예제 코드
import pandas as pd
data = {'value': [10, 20, 20, 30, 40, 50]}
df = pd.DataFrame(data)
# 상위 3개의 값을 구하기
top3 = df['value'].nlargest(3)
print(top3)
""" 출력 결과
5 50
4 40
3 30
Name: value, dtype: int64
"""
- 상위에서 3번째의 값을 뽑고자 할 경우, 다음과 같이 코드를 작성한다.
top3_value = top3.iloc[-1] # 마지막 행 값 선택
📎 문제 2 (21년 2회)
- housing 데이터
- 데이터의 첫 번째 행부터 순서대로 80%까지의 데이터를 훈련 데이터로 추출한 후, @total_bedrooms@ 변수의 결측값(NA)을 @total_bedrooms@ 변수의 중앙값으로 대체하고 대체 전의 @total_bedrooms@ 변수 표준편차 값과 대체 후의 @total_bedrooms@ 변수 표준편차 값의 차이의 절댓값 구하기
- 소수점 둘째 자리로 출력하기
import pandas as pd
df = pd.read_csv('./datasets/data_q2.csv')
# 상위 80%까지의 데이터를 훈련 데이터로 추출하기
nrow = int(len(df) * 0.8)
train_df = df[:nrow]
a = train_df['total_bedrooms'].std()
# total_bedrooms 변수의 결측값을 total_bedrooms 변수의 중앙값으로 대체
train_df['total_bedrooms'] = train_df['total_bedrooms'].fillna(train_df['total_bedrooms'].median())
b = train_df['total_bedrooms'].std()
# 대체 전의 total_bedrooms 변수 표준편차 값과 대체 후의 total_bedrooms 변수 표준편차 값의 차이의 절댓값 구하기
answer = round(abs(a - b), 2)
print(answer)
📌 상위 n%의 데이터 추출하기
- 데이터셋에서 상위 n%의 데이터를 추출하고할 경우, 다음과 같이 코드를 작성할 수 있다.
# 상위 n%의 데이터 추출하기
nrow = int(len(df) * (n / 100))
train_df = df[:nrow]
예제 코드
import pandas as pd
df = pd.read_csv('./datasets/data.csv')
# 상위 90%의 데이터를 훈련 데이터로 추출하기
nrow = int(len(df) * 0.9)
train_df = df[:nrow]
📎 문제 3 (21년 2회)
- Insurance 데이터
- @charges@ 항목에서 이상값의 합 구하기
- 이상값은 평균에서 1.5 표준편차 이상인 값으로 하고, 정수로 출력하기
import pandas as pd
df = pd.read_csv('./datasets/data_q3.csv')
# 이상값 -> x > upper or x < lower
# upper = 평균 + 1.5 * 표준편차
# lower = 평균 - 1.5 * 표준편차
target = df['charges']
mean_value = target.mean()
std_value = target.std()
upper = mean_value + 1.5 * std_value
lower = mean_value - 1.5 * std_value
cond = (target < lower) | (target > upper)
answer = int(target[cond].sum())
print(answer)
📌 이상치 탐색하기 : Upper Bound, Lower Bound
- 이상치(Outlier)를 탐색할 때, 데이터가 정상 범위에서 벗어난 값을 정의하기 위해 Upper Bound(상한)와 Lower Bound(하한)을 설정한다.
- Upper Bound와 Lower Bound는 데이터의 중심을 기준으로 데이터의 허용 가능한 범위를 설정한다.
- 일반적인 정의는 다음과 같다.
- Lower Bound = 평균(또는 중앙값) - k × 표준편차(또는 IQR)
- Upperr Bound = 평균(또는 중앙값) + k × 표준편차(또는 IQR)
- k : 조정 가능한 계수 (1.5 : 일반적, 3 : 극단적)
- 일반적인 정의는 다음과 같다.
- Upper Bound와 Lower Bound를 사용하면, 이상값의 범위는 다음과 같이 정의된다.
- 값 < Lower Bound : 하한보다 작은 값은 이상값으로 간주된다.
- 값 > Upper Bound : 상한보다 큰 값은 이상값으로 간주된다.
- 정상 범위의 값은 Lower Bound ≤ 값 ≤ Upper Bound 을 만족시킨다.
target = df['변수명']
mean_value = target.mean() # 평균
std_value = target.std() # 표준편차
upper = mean_value + 1.5 * std_value
lower = mean_value - 1.5 * std_value
cond = (target < lower) | (target > upper)
answer = target[cond]
📎 문제 4 (21년 3회)
- housing 데이터
- 결측값이 있는 모든 행을 제거한 후 데이터의 순서대로 상위 70%의 데이터를 학습 데이터로 만들고, 훈련 데이터의 @housing_median_age@ 컬럼의 제1사분위수(Q1) 구하기
- 정수로 출력하기
import pandas as pd
df = pd.read_csv('./datasets/data_q4.csv')
# 결측값이 있는 모든 행 제거하기
df = df.dropna()
# 데이터의 순서대로 상위 70%의 데이터를 훈련 데이터로 만들기
nrow = int(len(df) * 0.7)
train_df = df[:nrow]
# 훈련 데이터의 house_median_age 컬럼의 Q1 구하기
answer = int(train_df['housing_median_age'].quantile(0.25))
print(answer)
📌 제n사분위수 구하기(Qn) : @quantile()@
- @quantile@ 메서드를 이용하여 분위수(Quantile) 값을 구할 수 있다.
Series.quantile(q=0.5, interpolation='linear')
예제 코드
import pandas as pd
data = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
q1 = data.quantile(0.25) # 제1사분위수
q2 = data.quantile(0.50) # 제3사분위수 (중앙값)
q3 = data.quantile(0.75) # 제3사분위수
q4 = data.quantile(1.00) # 제4분위수 (최대값)
# 또는 다음과 같이 한번에 구할 수 있다.
q1, q2, q3, q4 = data.quantile([0.25, 0.50, 0.75, 1.00])
print(f"1st Quartile (Q1): {q1}")
print(f"2nd Quartile (Q2 - Median): {q2}")
print(f"3rd Quartile (Q3): {q3}")
print(f"4th Quartile (Q4 - Max): {q4}")
""" 출력 결과
1st Quartile (Q1): 2.75
2nd Quartile (Q2 - Median): 5.5
3rd Quartile (Q3): 8.25
4th Quartile (Q4 - Max): 10.0
"""
📎 문제 5 (21년 3회)
- 타이타닉 데이터
- 데이터가 없는 것을 결측값으로 하여 결측값의 비율을 구하고, 결측값 비율이 가장 높은 컬럼 이름 구하기
import pandas as pd
df = pd.read_csv('./datasets/data_q5.csv')
# 데이터가 없는 것을 결측값으로 하여 결측값의 비율 구하기
total_count = len(df)
missing_count = df.isna().sum()
ratio = missing_count / total_count
# 결측값의 비율이 가장 높은 컬럼 이름 구하기
ratio = pd.DataFrame(ratio)
sorted_ratio = ratio.sort_values(by=0, ascending=False)
print(sorted_ratio, '\n')
answer = sorted_ratio.index[0] # index[n]는 컬럼 이름을 반환한다.
print(answer)
📌 데이터프레임의 결측값 개수 확인하기 : @DataFrame.isna().sum()@
- 다음과 같이 데이터프레임(DataFrame)의 결측값(NA) 개수를 확인할 수 있다.
DataFrame.isna().sum()
📌 데이터프레임의 특정 컬럼을 기준으로 정렬하기
- 다음과 같이 데이터프레임(DataFrame)의 특정 컬럼을 기준으로 정렬 작업을 수행할 수 있다.
sorted_df = df.sort_values(by="컬럼명", ascending=False) # ascending : 오름차순 정렬 여부
- 정렬 작업을 수행하면 인덱스(index)의 값이 뒤죽 박죽되어 있는데, 다음과 같이 @reset_index(drop=True)@ 메서드를 이용하여 인덱스를 초기화시켜줄 수 있다.
- 또한 원본 데이터에 동일한 인덱스가 여러 개 있을 경우, 정렬 후에도 기존 인덱스가 그대로 남아 있어 중복이 발생할 수 있는데 @reset_index@ 메서드를 사용할 경우, 고유한 인덱스를 생성하여 인덱스의 중복을 방지할 수 있다.
- @drop=True@ 옵션을 지정하면, 원본 데이터의 인덱스 열을 새로운 열로 추가 하지 않고 제거한다.
sorted_df = df.sort_values(by='컬럼명', ascending=False).reset_index(drop=True)
정렬 작업 후, @iloc@ 또는 @loc@을 이용하여 데이터를 추출할 경우, @reset_index(drop=True)@ 메서드로 인덱스를 초기화해주는 것이 좋다.
예제 코드
import pandas as pd
# 예시 데이터프레임
data = {
'name': ['Alice', 'Bob', 'Charlie', 'David'],
'score': [90, 85, 88, 92]
}
df = pd.DataFrame(data)
# 데이터프레임에 'score'를 기준으로 내림차순 정렬
df_sorted = df.sort_values(by='score', ascending=False)
# reset_index를 사용하기 전
print("정렬 전 데이터프레임:")
print(df_sorted)
""" 출력 결과
정렬 전 데이터프레임:
name score
3 David 92
0 Alice 90
2 Charlie 88
1 Bob 85
"""
# reset_index(drop=False) 사용 후
df_reset = df_sorted.reset_index(drop=False)
print("reset_index(drop=False) 후:")
print(df_reset)
""" 출력 결과
reset_index(drop=False) 후:
index name score
0 3 David 92
1 0 Alice 90
2 2 Charlie 88
3 1 Bob 85
"""
# reset_index(drop=True) 사용 후
df_reset = df_sorted.reset_index(drop=True)
print("reset_index(drop=True) 후:")
print(df_reset)
""" 출력 결과
reset_index(drop=True) 후:
name score
0 David 92
1 Alice 90
2 Charlie 88
3 Bob 85
"""
📎 문제 6 (21년 3회)
- 연도별 각 국가의 결핵 감염에 대한 유병률 데이터
- @country@, @year@, @new_sp@ 컬럼에 결측값이 있을 경우 제거하고 2000년도에 국가별 결핵 발생 건수에 대한 평균 결핵 발생 건수를 구하고, 2000년도의 결핵 발생 건수가 2000년도 국가별 결핵 발생 건수에 대한 평균 결핵 발생 건수보다 결핵 발생 건수가 높은 국가의 개수 구하기
- 국가별 결핵 발생 건수에 대한 평균 결핵 발생 건수를 출력할 때, 소수점 둘째 자리로 출력하기
import pandas as pd
df = pd.read_csv('./datasets/data_q6.csv')
# country, year, new_sp 컬럼에서 결측값 제거하기
df['country'] = df['country'].dropna()
df['year'] = df['year'].dropna()
df['new_sp'] = df['new_sp'].dropna()
# 2000년도에 국가별 결핵 발생 건수에 대한 평균 결핵 발생 건수 구하기
cond = df['year'] == 2000
target_df = df[cond]
mean_count = round(target_df['new_sp'].mean(), 2)
print(mean_count)
# 2000년도의 결핵 발생 건수가 2000년도 국가별 결핵 발생 건수에 대한 평균 결핵 발생 건수보다 결핵 발생 건수가 높은 국가의 개수 구하기
cond = target_df['new_sp'] >= mean_count
answer = len(target_df[cond])
print(answer)
📎 문제 7 (22년 4회)
- 순서대로 처리하고 결과를 정수로 출력하기
- (1) y 변수의 1사분위와 3사분위 값 구하기
- (2) 3사분위수에서 1사분위수를 뺀 값 구하기
- (3) 소수점 이하는 버리고 정수로 출력하기
import pandas as pd
df = pd.read_csv('./datasets/data_q7.csv')
# (1) y 변수의 1사분위와 3사분위 값 구하기
target = df['y']
q1, q3 = target.quantile([0.25, 0.75])
# (2) 3사분위수에서 1사분위수를 뺀 값 구하기 (IQR)
diff_value = q3 - q1
# (3) 소수점 이하는 버리고 정수로 출력하기
answer = int(diff_value)
print(answer)
📎 문제 8 (22년 4회)
- 페이스북 평가 데이터
- '좋아요' 수(@num_loves@)와 '놀랐어요'(@num_wows@)를 긍정의 평가로 보고 전체 반응(@num_reactions@)에서 긍정인 비율이 0.4보다 크고 0.5보다 작은 비디오 개수 구하기
import pandas as pd
df = pd.read_csv('./datasets/data_q8.csv')
# 좋아요 수와 놀랐어요 수를 긍정의 평가로 보고 전체 중에서 비율 구하기
df['positive_ratio'] = (df['num_loves'] + df['num_wows']) / df['num_reactions']
# 전체 반응에서 긍정인 비율이 0.4보다 크고 0.5보다 작은 비디오 개수 구하기
cond = (df['status_type'] == 'video') & ((df['positive_ratio'] > 0.4) & (df['positive_ratio'] < 0.5))
answer = len(df[cond])
print(answer)
📎 문제 9 (22년 4회)
- 넷플릭스에서 사용된 작품들의 목록 데이터
- 2018년 1월에 넷플릭스에서 추가한 작품 중 @United Kingdom@에서 단독으로 제작된 작품의 개수 구하기
import pandas as pd
df = pd.read_csv('./datasets/data_q9.csv')
# 날짜 항목을 datetime64 형식으로 변환하기
df['date_added'] = pd.to_datetime(df['date_added'])
# 2018년 1월에 추가한 작품 중, 'United Kingdom'에서 단독으로 제작된 작품의 개수 구하기
cond1 = (df['date_added'].dt.year == 2018) & (df['date_added'].dt.month == 1)
cond2 = df['country'] == 'United Kingdom'
answer = len(df[cond1 & cond2])
print(answer)
📌 datetime64 형식으로 변환하기 : @pd.to_datetime()@
- @pd.to_datetime@ 함수는 판다스에서 문자열이나 다른 형식의 날짜/시간 데이터를 @datetime64@ 형식으로 변환해준다.
- 이 변환을 통해 날짜 데이터는 날짜와 시간 관련 연산을 할 수 있는 형태로 변환된다.
- 이러한 @datetime64@ 형식의 데이터는 @dt@ 접근자를 사용하여 날짜 관련 작업을 할 수 있다.
- 예) 연도/월/일 등의 정보 추출 가능
예제 코드
import pandas as pd
data = {'date_added': ['2023-01-01 10:15:30', '2023-02-15 14:30:45', '2023-03-20 18:45:59']}
df = pd.DataFrame(data)
# 'date_added' 열을 datetime64 형식으로 변환
df['date_added'] = pd.to_datetime(df['date_added'])
# 시간 정보 추출 후, 새로운 열에 저장
df['year'] = df['date_added'].dt.year # 연도
df['month'] = df['date_added'].dt.month # 월
df['day'] = df['date_added'].dt.day # 일
df['weekday'] = df['date_added'].dt.weekday # 요일 (0: 월요일, 6: 일요일)
df['hour'] = df['date_added'].dt.hour # 시간
df['minute'] = df['date_added'].dt.minute # 분
df['second'] = df['date_added'].dt.second # 초
df['microsecond'] = df['date_added'].dt.microsecond # 마이크로초
print(df)
""" 출력 결과
date_added year month day weekday hour minute second microsecond
0 2023-01-01 10:15:30 2023 1 1 6 10 15 30 0
1 2023-02-15 14:30:45 2023 2 15 2 14 30 45 0
2 2023-03-20 18:45:59 2023 3 20 0 18 45 59 0
"""
📎 문제 10 (22년 5회)
- 종량제 쓰레기 데이터
- 쓰레기 데이터에서 다음 기준에 따른 데이터를 추출하고, 평균 가격을 제출 형식에 따라 제출하기
- 종량제봉투종류 : 규격봉투
- 종량제봉투용도 : 음식물쓰레기
- 종량제봉투용량 : 2L
- 가격이 0인 것은 구매하지 않은 것으로, 평균 계산할 때 제외한다.
- 정수형으로 출력하기
import pandas as pd
df = pd.read_csv('./datasets/data_q10.csv', encoding='euckr')
# 종량제봉투종류 : 규격봉투, 종량제봉투용도 : 음식물쓰레기, 종량제봉투용량 : 2L (가격이 0인 것은 제외하기)
cond = (df['종량제봉투종류'] == '규격봉투') & (df['종량제봉투용도'] == '음식물쓰레기') & (df['2L가격'] != 0)
new_df = df[cond]
# 평균 가격 구하기
mean_price = new_df['2L가격'].mean()
answer = int(mean_price)
print(answer)
📎 문제 11 (22년 5회)
- Body 데이터
- 다음 기준에 의해 BMI를 계산하여 분류하고, 정상 체중 범위의 구간에 있는 인원과 위험 체중 범위의 구간에 있는 인원의 차이를 절댓값으로 구하기
- BMI = Weight / Height² (weight : kg, height : m)
- 저체중 : BMI < 18.5
- 정상체중 : 18.5 ≤ BMI < 23
- 위험체중 : 23 ≤ BMI < 25
- 비만 : 25 ≤ BMI
- BMI 계산시 단위에 유의하고, 정수로 출력하기
import pandas as pd
df = pd.read_csv('./datasets/data_q11.csv')
# BMI 계산하기
df['BMI'] = df['Weight'] / ((df['Height'] / 100) ** 2) # ✅ 단위에 주의할 것!
# 정상 체중 범위 구간의 인원 수와 위험 체중 범위 구간의 인원 수 구하기
cond1 = (18.5 <= df['BMI']) & (df['BMI'] < 23)
healthy = len(df[cond1])
cond2 = (23 <= df['BMI']) & (df['BMI'] < 25)
danger = len(df[cond2])
answer = int(abs(healthy - danger))
print(answer)
📎 문제 12 (22년 5회)
- 순전입학생수가 가장 큰 학교의 전체 학생수 구하기
- 순전입학생수 = 총전입학생수 - 총전출학생수
import pandas as pd
df = pd.read_csv('./datasets/data_q12.csv', encoding='euckr')
# 순전입학생수 구하기 (순전입학생수 = 총전입학생수 - 총전출학생수)
df['순전입학생수'] = df['전입학생수(계)'] - df['전출학생수(계)']
# 순전입학생수가 가장 큰 학교의 전체 학생수 구하기
new_df = df.sort_values(by='순전입학생수', ascending=False).reset_index(drop=True)
answer = new_df['전체학생수(계)'].iloc[0]
print(answer)
📎 문제 13 (23년 6회)
- 출동소방서별로 주민으로부터 연락받은 신고일시와 출동한 출동일시를 기록한 데이터
- 출동소방서별 신고일시로부터 출동일시까지의 연도별 월평균을 구하고, 가장 늦게 출동한 출동소방서의 월평균 시간을 분단위로 제출 형식에 맞게 제출하기
- 시간은 30초 단위로 반올림하여 제출하기
import pandas as pd
df = pd.read_csv('./datasets/data_q13.csv')
# 신고일시, 출동일시 컬럼을 datetime64 형식으로 변환하기
df['신고일시'] = pd.to_datetime(df['신고일시'])
df['출동일시'] = pd.to_datetime(df['출동일시'])
# 출동소방서별 신고일시로부터 출동일시까지 연도별 월평균 구하기
df['시간차이'] = (df['출동일시'] - df['신고일시']).dt.total_seconds()
df = df.groupby([df['출동소방서'], df['신고일시'].dt.year, df['신고일시'].dt.month]).mean('시간차이')
df = df.sort_values(by='시간차이', ascending=False)
# 가장 늦게 출동한 출동소방서의 월평균 시간을 분단위로 나타내기
result_date = df['시간차이'].head(1)
result_num = float(result_date.iloc[0]) / 60 # 분단위
answer = int(result_num)
print(answer)
📌 전체 시간을 초 단위로 바꾸기 : @Series.dt.total_seconds()@
- @datetime64@ 형식의 시간 데이터를 초(Second) 단위로 바꾸려면 다음과 같이 코드를 작성한다.
Series.dt.total_seconds()
📎 문제 14 (23년 6회)
- 초등학교의 학년별 학생 수와 교사 수를 기록한 데이터
- 교사 1인당 학생 수가 가장 많은 학교를 선정하고, 선정된 학교의 교사 수를 제출 형식에 맞게 제출하기
- 학교명 중복은 없고, 단일 학교의 학생 수, 교사 수 데이터만 있는 것으로 한다.
import pandas as pd
df = pd.read_csv('./datasets/data_q14.csv')
# 교사 1인당 학생수가 가장 많은 학교 선정하기
df['student_number_per_teacher'] = (df['student_1'] + df['student_2'] + df['student_3'] + df['student_4'] + df['student_5'] + df['student_6']) / df['teacher']
df_sorted = df.sort_values(by='student_number_per_teacher', ascending=False)
target_df = df_sorted.head(1)
# 선정된 학교의 교사수 구하기
answer = target_df['teacher'].iloc[0]
print(answer)
📎 문제 15 (23년 6회)
- 월별 범죄를 기록한 데이터
- 연도별 월평균 범죄 건수를 구하고, 가장 범죄가 많이 발생한 연도의 월평균 범죄 건수 구하기
- 파이썬의 경우 CSV 파일을 읽을 때 @index_col=0@ 옵션을 적용한다.
import pandas as pd
df = pd.read_csv('./datasets/data_q15.csv')
# 년월 컬럼을 datetime64 컬럼으로 바꾸기
df['년월'] = pd.to_datetime(df['년월'])
# 연도별 월평균 범죄 건수 구하기
df['발생연도'] = df['년월'].dt.year
df['발생월'] = df['년월'].dt.month
df['총범죄건수'] = df['강력범'] + df['절도범'] + df['폭력범'] + df['지능범'] + df['풍속범'] + df['기타형사범']
df = df.groupby(by=['발생연도']).mean() # 월평균 범죄 건수
# 가장 범죄가 많이 발생한 연도의 월평균 범죄 건수 구하기
df_sorted = df.sort_values(by='총범죄건수', ascending=False)
target_df = df_sorted.head(1)
answer = int(target_df['총범죄건수'].iloc[0])
print(answer)
📎 문제 16 (23년 7회)
- 학생 15명의 국어, 수학, 영어, 과학 시험 점수 (각 학생은 4과목 중 3과목을 선택해서 시험봤다.)
- 국어, 수학, 영어, 과학 과목 중 가장 많은 학생들이 응시한 시험을 선택하고, 해당 과목의 점수를 표준화 했을 때 가장 큰 표준화 점수 구하기
import pandas as pd
from scipy.stats import zscore
df = pd.read_csv('./datasets/data_q16.csv')
# 각 과목별 결측치 제거 후 개수 파악하기
count_korean = df['국어'].dropna().count()
count_math = df['수학'].dropna().count()
count_english = df['영어'].dropna().count()
count_science = df['과학'].dropna().count()
print(count_korean, count_math, count_english, count_science)
target = df['국어']
# 표준화 (Z-점수 표준화 = X-평균 / 표준편차) 후 가장 큰 점수 구하기
target = target.dropna() # 결측치 제거
answer = zscore(target).max()
print(answer)
📌 표준화 하기 : @zscore()@
- 표준화(Standardization)란, 어떤 특정의 값들이 정규 분포를 따른다고 가정하고 값들을 @0@의 평균, @1@의 표준편차를 갖도록 해주는 기법이다.
- Z-score는 각 값이 평균에서 얼마나 떨어져 있는지를 표준편차 단위로 나타낸 값이다.
- X의 값이 평균과 일치하면 @0@, 평균보다 작으면 음수, 평균보다 크면 양수가 되며, 표준편차가 크면 Z-스코어는 @0@에 가까워진다.
- @scipy.stats@ 패키지의 @zscore()@ 함수를 이용하여 간단하게 Z-score 표준화를 진행할 수 있다.
import pandas as pd
from scipy.stats import zscore
data = {
'A': [10, 20, 30, 40, 50],
'B': [100, 200, 300, 400, 500],
'C': [5, 10, 15, 20, 25]
}
df = pd.DataFrame(data)
target_df = df['A']
# 각 열에 zscore를 적용하여 표준화
df_standardized = zscore(target_df)
print("Original DataFrame (Column A):")
print(df['A'])
""" 출력 결과
Original DataFrame (Column A):
0 10
1 20
2 30
3 40
4 50
Name: A, dtype: int64
"""
print("Standardized DataFrame (Column A):")
print(df['A'])
""" 출력 결과
Standardized DataFrame (Column A):
0 -1.264911
1 -0.632456
2 0.000000
3 0.632456
4 1.264911
Name: A, dtype: float64
"""
📎 문제 17 (23년 7회)
- 32개 변수간 상관 관계를 확인했을 때, @var_11@ 컬럼과 상관 계수의 절댓값이 가장 큰 변수를 찾아 해당 변수의 평균값 구하기
import pandas as pd
df = pd.read_csv('./datasets/data_q17.csv')
# var_11 컬럼과 상관 계수의 절댓값이 가장 큰 변수 찾기
df_corr = df.corr(numeric_only=True) # 상관 계수 구하기
target = df_corr['var_11']
abs_target = np.abs(target) # 절댓값 씌우기
sorted_target = abs_target.sort_values(ascending=False) # 내림차순 정렬
result_variable = sorted_target.index[1]
print(result_variable) # 변수명
print(sorted_target['var_44']) # 변수값
# 찾은 변수의 평균값 구하기
answer = df[result_variable].mean()
print(answer)
📌 상관 계수 구하기 : @DataFrame.corr()@
- @DataFrame.corr()@ 함수를 이용하여 변수 간 상관 계수를 확인할 수 있다.
df_corr = df.corr(numeric_only=True)
- 판다스 2.0.0 버전(빅데이터분석기사 실기 9회차)부터 @corr()@ 함수를 사용할 때, 반드시 @numeric_only=True@ 옵션을 지정해야 한다.
- 관련 내용은 이곳을 참고한다.
예제 코드
import numpy as np
import pandas as pd
data = {
'var_1': [1, 2, 3, 4, 5],
'var_2': [2, 3, 4, 5, 6],
'var_3': [5, 4, 3, 2, 1],
'var_4': [10, 20, 30, 40, 50],
'var_5': [1, 1, 2, 3, 5]
}
df = pd.DataFrame(data)
# 상관 계수 구하기
df_corr = df.corr(numeric_only=True)
pritn(df_corr)
""" 출력 결과
var_1 var_2 var_3 var_4 var_5
var_1 1.000000 1.000000 -1.000000 1.000000 0.989743
var_2 1.000000 1.000000 -1.000000 1.000000 0.989743
var_3 -1.000000 -1.000000 1.000000 -1.000000 -0.989743
var_4 1.000000 1.000000 -1.000000 1.000000 0.989743
var_5 0.989743 0.989743 -0.989743 0.989743 1.000000
"""
📎 문제 18 (23년 7회)
- @var_6@ 컬럼의 1, 3사분위수에서 각각 IQR의 1.5배 벗어난 이상치의 숫자 구하기
import pandas as pd
df = pd.read_csv('./datasets/data_q18.csv')
# var_6 컬럼의 1, 3사분위수를 구하고, IQR 구하기
target = df['var_6']
q1, q3 = target.quantile([0.25, 0.75])
iqr = q3 - q1
# IQR의 1.5배 벗어난 이상치 숫자 구하기
lower = q1 - 1.5 * iqr
upper = q3 + 1.5 * iqr
cond = (target < lower) | (target > upper)
answer = len(df[cond]['var_6'])
print(answer)
📌 이상치 탐색하기 : IQR(Interquartile Range)
- IQR (Interquartile Range)을 이용한 이상치 탐색은 데이터 분포에서 중앙 50%의 범위를 이용하여, 그 범위를 벗어나는 값을 이상치로 판별하는 방법이다.
- IQR은 제1사분위수(Q1)와 제3사분위수(Q3) 차이로 정의된다.
- IQR을 이용할 경우, Upper Bound(상한)과 Lower Bound(하한)를 다음과 같이 정의할 수 있다.
- Upper Bound : Q3 + 1.5 × IQR
- Lower Bound : Q1 - 1.5 × IQR
- Upper Bound와 Lower Bound의 범위를 벗어난 데이터는 이상치로 간주된다.
예제 코드
import pandas as pd
data = {
'A': [1, 2, 3, 4, 5, 100],
'B': [10, 12, 13, 14, 15, 500],
'C': [30, 31, 32, 33, 34, 500]
}
df = pd.DataFrame(data)
target = df['A']
q1, q3 = target.quantile([0.25, 0.75])
iqr = q3 - q1
upper_bound = q1 + 1.5 * iqr
lower_bound = q1 - 1.5 * iqr
cond = (target > upper_bound) | (target < lower_bound)
outliers_count = len(target[cond])
print(outliers_count)
""" 출력 결과
1
"""
📎 문제 19 (24년 8회)
- 대륙별 평균 맥주 소비량이 많은 곳을 고르고, 해당 대륙에서 다섯번째로 맥주 소비량이 많은 나라 구하기
- 정수로 나타내기
import pandas as pd
df = pd.read_csv('./datasets/data_q19.csv')
# 대륙별 평균 맥주 소비량 가장 많은 곳 구하기
new_df = df.groupby(by='continent')['beer_servings'].mean()
new_df = new_df.sort_values(ascending=False)
continent = new_df.index[0]
# 해당 대륙에서 다섯번째로 맥주 소비량이 많은 나라 구하기
cond = df['continent'] == 'Europe'
df_europe = df[cond]
sorted_df_europe = df_europe.sort_values(by="beer_servings", ascending=False).reset_index()
# 맥주 소비량 다섯번째로 큰 나라의 맥주 소비량 구하기
answer = sorted_df_europe.iloc[4]['beer_servings']
print(answer)
📌 특정 컬럼 기준으로 그룹화 하기 : @DataFrame.groupby(by="컬럼명")@
- @DataFrame.groupby(by="컬럼명")@는 데이터를 특정 컬럼을 기준으로 그룹화할 때 사용한다.
- 데이터프레임을 하나 이상의 컬럼에 따라 그룹으로 나누고, 각 그룹에 대해 집계 작업(평균, 총합 등 구하기)을 수행하거나 변환할 수 있게 해준다.
- 집계 함수 : @sum()@, @mean()@, @count()@, @min()@, @max()@
- @agg()@ 메서드를 사용하여 여러 집계 함수들을 동시에 적용할 수 있다.
- 예) @grouped.agg({'Value': ['sum', 'mean', 'max']})@
- @filter()@를 사용하여 조건에 맞는 그룹만 필터링할 수 있다.
- 예) @grouped.filter(lambda x: len(x) > 2)@ (그룹 크기가 2보다 큰 그룹만 반환)
DataFrame.groupby(by="컬럼명")
- @by@ 매개변수에 여러 개의 컬럼을 리스트 형태로 전달하면 여러 컬럼을 기준으로 그룹화할 수 있다.
df.groupby(by=['Category', 'Value'])
예제 코드
import pandas as pd
data = {
'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
'Value': [10, 20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)
# 'Category' 컬럼을 기준으로 그룹화
grouped = df.groupby(by="Category")
# 각 그룹에 대해 합계를 계산
sum_grouped = grouped.sum()
print(sum_grouped)
""" 출력 결과
Value
Category
A 90
B 120
"""
📎 문제 20 (24년 8회)
- 관광객 비율이 두 번째로 높은 나라의 @관광@ 수를 @a@라고 정의하고, 관광객 수가 두 번째로 높은 나라의 @공무@ 수를 @b@라고 정의한 후, a+b의 값 구하기
- 관광객 비율 - 관광 입국 인원 / (관광 입국 인원 + 공무 입국 인원)
import pandas as pd
data = {
'국가': ['홍콩', '독일', '일본', '중국', '미국'],
'관광입국': [74, 50, 100, 120, 60],
'공무입국': [38, 26, 165, 60, 90],
}
df = pd.DataFrame(data)
# 관광객 비율 구하기
df['관광객비율'] = df['관광입국'] / (df['관광입국'] + df['공무입국'])
# 관광객 비율 기준 내림차순 정렬
ratio_sorted_df = df.sort_values(by="관광객비율", ascending=False).reset_index(drop=True)
print(ratio_sorted_df)
# 관광객 비율이 두 번째로 높은 나라의 관광입국 수 구하기
a = ratio_sorted_df.loc[1, '관광입국']
print(a)
# 관광객 수 기준 내림차순 정렬
tour_sorted_df = df.sort_values(by="관광입국", ascending=False).reset_index(drop=True)
print(tour_sorted_df)
# 관광객 수가 두 번째로 높은 나라의 공무입국 수 구하기
b = tour_sorted_df.loc[1, '공무입국']
print(b)
answer = a + b
print(answer)
📎 문제 21 (24년 8회)
- @Co@ 컬럼과 @Nmch@ 컬럼을 Min-Max Scaling 시행한 다음, 스케일링 후의 @Co@ 컬럼의 표준편차를 @a@라 하고, @Nmch@ 컬럼의 표준편차를 @b@로 한 후, a-b의 값 구하기
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
np.random.seed(10)
data = {
'Co': np.random.uniform(50, 300, 100),
'Nmch': np.random.uniform(20, 100, 100)
}
df = pd.DataFrame(data)
# 최소-최대 정규화 시행하기
mms = MinMaxScaler()
df[['Co_scaled', 'Nmch_scaled']] = mms.fit_transform(df[['Co', 'Nmch']])
# 표준편차 구하기
a = df['Co_scaled'].std()
b = df['Nmch_scaled'].std()
# 정답 구하기
## 💡 문제에서 'a-b' 라고 식을 정의해주었으므로 마이너스를 꼭 붙여야 한다.
answer = a - b
print(answer)
📌 데이터 스케일링하기 : 최소-최대 정규화(@MinMaxScaler()@)
- 최소-최대 정규화(Min-Max Scaling)는 데이터를 0과 1 사이로 변환하는 기법이다.
- 이 기법은 데이터를 특정 범위로 압축하여 데이터의 분포를 일정한 범위로 맞춰준다.
- 이때 각 특성(피쳐)은 최소값과 최대값을 기준으로 선형적으로 변환된다.
$$X_{scaled} = \frac{X - X_{min}}{X_{max} - X_{min}}$$
- 사이킷런(@sklearn@)의 @MinMaxScaler()@ 함수를 사용하여 간단하게 최소-최대 정규화를 수행할 수 있다.
from sklearn.preprocessing import MinMaxScaler
df = pd.read_csv('./datasets/data.csv')
target_columns = ['컬럼A', '컬럼B']
mms = MinMaxScaler()
df[target_columns] = mms.fit_transform(df[target_columns])
📎 문제 22 (시험장 환경 체험 예제)
- 제공된 데이터(@data/mtcars@)의 @qsec@ 컬럼을 최소-최대 척도(Min-Max Scale)로 변환한 후, 0.5보다 큰 값을 가지는 레코드 수 구하기
- 정수로 출력하기
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
df = pd.read_csv('./datasets/data_q22.csv')
# qsec 컬럼을 최소-최대 척도로 변환하기
mms = MinMaxScaler()
df['qsec'] = mms.fit_transform(df[['qsec']]) # 2차원 데이터를 인수로 넣어준다! ✅
# 0.5보다 큰 값을 가지는 레코드 수 구하기
cond = df['qsec'] > 0.5
answer = len(df[cond])
print(answer)
728x90
728x90
'Certificate > 빅데이터분석기사' 카테고리의 다른 글
[빅데이터분석기사 실기] 피어슨 상관 계수 구하기 (2) | 2024.11.30 |
---|---|
[빅데이터분석기사 실기] 시험장에서 알아두면 좋은 팁 (0) | 2024.11.29 |
[빅데이터분석기사 실기] 제3유형: 가설 검정 연습 문제 (0) | 2024.11.27 |
[빅데이터분석기사 실기] 제2유형 시험 준비 (0) | 2024.11.26 |
[빅데이터분석기사 실기] help(), dir() 활용하기 (0) | 2024.11.25 |
[빅데이터분석기사 실기] corr() 함수와 numeric_only 옵션 (0) | 2024.11.25 |
[빅데이터분석기사 실기] 시험장 들어가기 전에 보기 빠르게 보기 좋은 강의 모음 (1) | 2024.11.17 |
[빅데이터분석기사 실기] 제6회 기출 변형 문제 (제3유형) (0) | 2024.11.16 |