[Numpy] 데이터 분석 실습 문제
[문제] BMI 지수 계산 및 과체중 이상인 BMI 값 확인
- 10명에 대한 키와 몸무게가 들어있는 'height_weight.txt'를 읽어 각 사람별 BMI 지수를 구하고 비만 전단계 이상인 BMI 값 확인하기
BMI 지수 = 몸무게(kg) / 키(M)의 제곱
체질량지수의 범위 값에 따른 비만도 값 지정
18.5 미만 ▶ 저체중
18.5 ~ 22.9 ▶ 정상
23 ~ 24.9 ▶ 비만 전단계
25 ~ 29 ▶ 1단계 비만
30 ~ 34.9 ▶ 2단계 비만
35이상 ▶ 고도비만
# Numpy 배열 출력 형식 변경 (소수점 이하 3자리까지)
np.set_printoptions(precision=3, suppress=True)
import numpy as np
data = np.loadtxt('height_weight.txt', delimiter=',')
print(data)
# BMI 값 구하기
height = (data[0] * 0.01) ** 2
weight = data[1]
BMI = weight / height
print(BMI)
# 비만 전단계 이상인 BMI 값 확인하기
print(BMI[BMI >= 23])
# 비만 전단계인 BMI 값 확인하기
print(BMI[np.logical_and(BMI >= 23, BMI < 25)])
[[175.2 180.3 175. 169.2 185.2 188. 177.6 178.2 177. 179. ]
[ 65.6 88. 79.2 69.3 55. 71.2 73. 68.9 74. 82. ]]
[21.372 27.07 25.861 24.207 16.035 20.145 23.144 21.697 23.62 25.592]
[27.07 25.861 24.207 23.144 23.62 25.592]
[24.207 23.144 23.62 ]
[문제] 국가건강검진 혈압혈당 데이터 분석
* '국가건강검진_혈압혈당데이터.csv' 파일 내용을 읽기 <data = np.loadtxt("국가건강검진_혈압혈당데이터.csv", delimiter=",", dtype=np.float32, skiprows=1)>
- 성별: 1(남자), 2(여자)
- 연령그룹: 1(20-24), 2(25-26),...25-74세까지 2살 간격으로 1개 그룹으로 지정, 27(74세 이상)
- 고혈압 당뇨병 진료여부: 1(고혈압 및 당뇨진료내역 있음), 2(고혈압 진료내역 있음), 3(당뇨 진료내역 있음), 4(고혈압 및 당뇨 진료내역 없음)
- 정상혈압: 수축기 혈압 120nnHg 미만, 확장기 혈압 80mmHg 미만
- 공복혈당 수치: 126 mg/dL 이상 -> 당뇨병, 100mg/dL-> 정상
* 전체 레코드 수와 상위 5개 데이터 확인
* 데이터 모양 확인
* 여성과 남성의 데이터 수 확인
* 여성과 남성의 수축기혈압과 이완기혈압의 평균값 확인
* 정상 혈압 남자 및 여자 수 확인
* 당뇨병 질환(공복혈당 수치 126mg/dL 이상)을 가지고 있는 사람들의 평균 체질량지수
import numpy as np
data = np.loadtxt("국가건강검진_혈압혈당데이터.csv", delimiter=",", dtype=np.float32, skiprows=1)
# 데이터 모양 확인
print(data.shape) # (1000000, 7)
# 상위 5개 데이터 확인
print(data[:5])
[[ 1. 1. 116. 78. 94. 4. 16.6]
[ 1. 1. 100. 60. 79. 4. 22.3]
[ 1. 1. 100. 60. 87. 4. 21.9]
[ 1. 1. 111. 70. 72. 4. 20.2]
[ 1. 1. 120. 80. 98. 4. 20. ]]
# 각 컬럼별 유니크 값 확인
print('성별 값:', np.unique(data[:,0])) # 전체 행에 0번째 컬럼
print('고혈압 당뇨병 진료여부 값:', np.unique(data[:,5]))
성별 값: [1. 2.]
고혈압 당뇨병 진료여부 값: [1. 2. 3. 4.]
# 여성과 남성의 데이터 수 확인
male = data[:, 0] == 1
female = data[:, 0] == 2
print(f'남성 데이터 수: {np.sum(male):,}개')
print(f'여성 데이터 수: {np.sum(female):,}개')
남성 데이터 수: 510,227개
여성 데이터 수: 489,773개
# 여성과 남성의 수축기혈압과 이완기혈압의 평균값 확인
male_sbp_mean = np.mean(data[male][:, 2])
print(f'남성의 수축기혈압 평균: {male_sbp_mean:.2f}')
male_dbp_mean = np.mean(data[male][:, 3])
print(f'남성 이완기혈압 평균: {male_dbp_mean:.2f}')
female_sbp_mean = np.mean(data[female][:, 2])
print(f'여성 수축기혈압 평균: {female_sbp_mean:.2f}')
female_dbp_mean = np.mean(data[female][:, 3])
print(f'여성 이완기혈압 평균: {female_dbp_mean:.2f}')
남성의 수축기혈압 평균: 124.28
남성 이완기혈압 평균: 77.61
여성 수축기혈압 평균: 119.36
여성 이완기혈압 평균: 73.88
# 정상 혈압 남자 및 여자 수 확인
# 정상혈압: 수축기 혈압 120nnHg 미만, 확장기 혈압 80mmHg 미만
normalBP = np.logical_and(data[:, 2] < 120, data[:, 3] < 80)
nbp = data[normalBP]
print(f'정상혈압 남성 수: {len(nbp[nbp[:,0]==1]):,}명') # 데이터 값은 len을 이용
# print(f'정상혈압 남성 수: {nbp[:,0]==1:,}명') boolean 값은 sum을 이용
print(f'정상혈압 여성 수: {len(nbp[nbp[:,0]==2]):,}명')
# 당뇨병 질환(공복혈당 수치 126mg/dL 이상)을 가지고 있는 사람들의 평균 체질량지수
diabetes = data[data[:, 4] >= 126]
print('당뇨병 질환을 가지고 있는 사람들의 평균 체질량지수:', np.mean(diabetes[:,6]))
정상혈압 남성 수: 158,007명
정상혈압 여성 수: 230,707명
당뇨병 질환을 가지고 있는 사람들의 평균 체질량지수: 25.168697
[문제] 시에틀 강수량 데이터 분석
- 'Seattle2014.csv' 파일 내용 읽기
- 강수량('PRCP')이 많은 날 상위 10일 확인
- 1월 강수량만 출력
- 1월에 내린 강수량의 합, 평균강수량 확인
- 1년동안 강수량이 40미만으로 내린 날이 몇일인가?
# 문자열 데이터가 포함되어 있어 모든 데이터를 문자열(object)로 가져오기
data = np.loadtxt("Seattle2014.csv", delimiter=",", skiprows=1, dtype=object)
print(data[:5])
print(data.shape) # (365, 17)
[['GHCND:USW00024233' 'SEATTLE TACOMA INTERNATIONAL AIRPORT WA US'
'20140101' '0' '0' '0' '72' '33' '12' '340' '310' '36' '40' '-9999'
'-9999' '-9999' '-9999']
['GHCND:USW00024233' 'SEATTLE TACOMA INTERNATIONAL AIRPORT WA US'
'20140102' '41' '0' '0' '106' '61' '32' '190' '200' '94' '116' '-9999'
'-9999' '-9999' '-9999']
['GHCND:USW00024233' 'SEATTLE TACOMA INTERNATIONAL AIRPORT WA US'
'20140103' '15' '0' '0' '89' '28' '26' '30' '50' '63' '72' '1' '-9999'
'-9999' '-9999']
['GHCND:USW00024233' 'SEATTLE TACOMA INTERNATIONAL AIRPORT WA US'
'20140104' '0' '0' '0' '78' '6' '27' '40' '40' '45' '58' '1' '-9999'
'-9999' '-9999']
['GHCND:USW00024233' 'SEATTLE TACOMA INTERNATIONAL AIRPORT WA US'
'20140105' '0' '0' '0' '83' '-5' '37' '10' '10' '67' '76' '-9999'
'-9999' '-9999' '-9999']]
(365, 17)
# 강수량('PRCP')이 많은 날 상위 10일 확인
PRCP = np.sort(data[:,3].astype(int))[::-1]
print(PRCP[:10])
[467 343 333 323 320 277 264 254 221 216]
# 상위 10일 with date
prcp_data = data[:, [2,3]].astype(int)
sorted_idx = prcp_data[:,1].argsort() # 강수량 기준으로 오름차순한 데이터의 인덱스 값
print(prcp_data[sorted_idx][::-1][:10])
[[20140305 467]
[20141128 343]
[20140503 333]
[20140308 323]
[20141022 320]
[20140316 277]
[20140216 264]
[20141030 254]
[20140328 221]
[20140129 216]]
# 1월 강수량만 출력 - 방법 1
prcp_data = data[:, [2,3]].astype(int)
jan_prcp = prcp_data[prcp_data[:,0] <= 20140131]
print(jan_prcp[:,1])
# 1월 강수량만 출력 - 방법 2
prcp_data = data[:, [2,3]].astype(int)
prcp_data[:,0] = (prcp_data[:,0] - 20140000) // 100 # date의 월만 출력
jan_prcp = prcp_data[prcp_data[:,0] == 1] # 1월만 가져옴
print(jan_prcp[:,1])
# 1월 강수량만 출력 - 방법 3
prcp_data = data[:, [2,3]] # 문자열 형태 그대로 가져옴
prcp_data = np.array([[date[4:6], prcp] for date, prcp in prcp_data])
# date[4:6] : 날짜에서 월만 뺀 것 / prcp : 강수량
jan_prcp = prcp_data[prcp_data[:,0] == '01'][:,1].astype(int) # 1월에 해당하는 강수량을 정수로 변환해서 가져옴
print(jan_prcp)
[ 0 41 15 0 0 3 122 97 58 43 213 15 0 0 0 0 0 0
0 0 0 5 0 0 0 0 0 89 216 0 23]
# 1월에 내린 강수량의 합, 평균강수량 확인
print(f'1월 강수량 총합: {np.sum(jan_prcp)}')
print(f'1월 강수량 평균: {np.mean(jan_prcp):.2f}')
1월 강수량 총합: 940
1월 강수량 평균: 30.32
# 1년동안 강수량이 40미만으로 내린 날이 몇일인가? (방법-1)
print(len(date_prcp[:,1][date_prcp[:,1] < 40])) # 277
# 1년동안 강수량이 40미만으로 내린 날이 몇일인가? (방법-2)
prcp_data = data[:, 3].astype(int)
under_40 = prcp_data[prcp_data < 40]
print(under_40.size) # size : 데이터의 개수 출력
[문제] 영화 평점 분석
- 'ratings.dat' 파일 내용 읽기 (데이터 형식: user_id:item_id:rating:timestamp)
- 상위 10개 데이터 출력하기
- 데이터 정보 확인(크기, 차원)
- 전체 데이터 평균 평점 구하기
- 사용자 아이디 1인 데이터 출력하기
- 사용자 아이디 1인 사람의 평점 평균 구하기
- 각 사용자별 평점 구하기 (사용자 ID 수집: ID컬럼에 대한 np.unique() 함수 적용)
- 각 사용자별 평균 평점이 4점 이상인 사용자 및 인원수 구하기
data = np.loadtxt("ratings.dat", delimiter=":", dtype=np.int32)
print(data[:10])
print(data.shape) # (1000209, 4)
[[ 1 1193 5 978300760]
[ 1 661 3 978302109]
[ 1 914 3 978301968]
[ 1 3408 4 978300275]
[ 1 2355 5 978824291]
[ 1 1197 3 978302268]
[ 1 1287 5 978302039]
[ 1 2804 5 978300719]
[ 1 594 4 978302268]
[ 1 919 4 978301368]]
(1000209, 4)
# 전체 데이터 평균 평점 구하기
print(f'전체 사용자 평균 평점: {np.mean(data[:,2]):.2f}')
전체 사용자 평균 평점: 3.58
# 사용자 아이디 1인 데이터 출력하기
id_1 = data[data[:,0] == 1]
print(id_1[:10])
[[ 1 1193 5 978300760]
[ 1 661 3 978302109]
[ 1 914 3 978301968]
[ 1 3408 4 978300275]
[ 1 2355 5 978824291]
[ 1 1197 3 978302268]
[ 1 1287 5 978302039]
[ 1 2804 5 978300719]
[ 1 594 4 978302268]
[ 1 919 4 978301368]]
# 사용자 아이디 1인 사람의 평점 평균 구하기
print(f'아이디 1인 사람의 평균 평점: {np.mean(id_1[:,2]):.2f}')
아이디 1인 사람의 평균 평점: 4.19
# 각 사용자별 평균 평점 구하기 (사용자 ID 수집: ID컬럼에 대한 np.unique() 함수 적용)
user_id = np.unique(data[:,0])
print(f'전체 사용자 수: {user_id.size:,}명')
id_rate = [[id, np.mean(data[data[:,0]==id][:,2])] for id in user_id]
for id, rate in id_rate[:10]:
print(f'{id} : {rate:.2f}')
전체 사용자 수: 6,040명
1 : 4.19
2 : 3.71
3 : 3.90
4 : 4.19
5 : 3.15
6 : 3.90
7 : 4.32
8 : 3.88
9 : 3.74
10 : 4.11
# 각 사용자별 평균 평점이 4점 이상인 사용자 수 구하기
id_rate = np.array(id_rate)
print(f'평균 평점이 4 이상인 사용자 수: {np.sum(id_rate[:,1]>=4):,}명')
평균 평점이 4 이상인 사용자 수: 1,544명