오늘은 pandas의 DataFrame으로 데이터를 조회하고 조건별로 집계했다. 이어서 Matplotlib으로 그래프를 그리고, 평균·편차·분산·표준편차를 계산해봤다.
지난 시간의 Series에서 행과 열을 가진 표로 넘어가, 데이터를 골라 보고 시각화하는 흐름까지 실습했다.
타이타닉 CSV를 불러온 뒤 shape, info(), describe()로 구조와 통계량을 확인했다. 실습 데이터는 891행, 12열이었고, 나이인 Age는 값이 있는 행이 714개였다.
컬럼을 선택할 때도 반환 형태가 달랐다.
titanic_df["Name"] # Series
titanic_df[["Name"]] # DataFrame
titanic_df[["Name", "Age"]] # 여러 컬럼 선택
행을 고를 때는 라벨 기준인 loc와 위치 기준인 iloc를 비교했다.
titanic_df.loc[:3] # 이 데이터에서는 라벨 0~3
titanic_df.iloc[:3] # 처음 3개 행
10행 간격으로 추린 titanic_df[::10]에 iloc[3]을 사용하면 라벨 30인 행이 나왔다. 인덱스에 적힌 숫자와 현재 데이터에서의 위치를 구분해야 했다.
여성 생존자는 두 조건을 &로 연결해 조회했다.
fe_su_mask = (
(titanic_df["Sex"] == "female")
& (titanic_df["Survived"] == 1)
)
survived_female = titanic_df[fe_su_mask]
이 데이터에서 여성은 314명, 여성 생존자는 233명으로 계산한 생존율은 약 74.2%였다.
객실 등급별 생존율은 조건으로 각각 구한 뒤 groupby()로도 확인했다.
titanic_df.groupby("Pclass")["Survived"].agg(["mean", "count"])
Survived가 0과 1로 되어 있어 평균이 생존 비율이 된다.
| 객실 등급 | 데이터 수 | 생존율 |
|---|---|---|
| 1등석 | 216 | 62.96% |
| 2등석 | 184 | 47.28% |
| 3등석 | 491 | 24.24% |
위 수치는 실습에 사용한 891개 기록을 기준으로 한 결과다. 전체 탑승객의 통계나 차이가 생긴 원인까지 확인한 것은 아니다.
apply()로 나이에 따라 분류하는 컬럼도 만들었다. 실습 기준은 19세 이상이면 성인, 그 미만이면 아이였다.
def get_adult(age):
if pd.isna(age):
return "알 수 없음"
return "성인" if age >= 19 else "아이"
titanic_df["IsAdult"] = titanic_df["Age"].apply(get_adult)
나이가 없는 행은 먼저 따로 처리했다. 조건만 비교해서 분류하면 결측값을 의도하지 않은 범주에 넣을 수 있기 때문이다.
컬럼을 만든 뒤에는 drop(..., axis=1)로 삭제하는 것도 연습했다.
Matplotlib에서는 선 그래프, 막대그래프, 히스토그램, 산점도를 그렸다. 배열과 난수 데이터, DataFrame을 사용한 기초 예제였다.
plt.figure(figsize=(10, 5))
plt.plot(test_df)
plt.ylabel("y축")
plt.xlabel("x축")
plt.legend(test_df.columns)
plt.show()
그래프 크기와 축 이름, 범례를 지정하고 선 색상·마커·스타일도 바꿔봤다. 한글 표시를 위해 맑은 고딕 설정도 사용했다.
하나의 Figure를 2×2로 나눈 뒤, 각 영역에 히스토그램·선 그래프·산점도·막대그래프를 배치하는 실습도 했다. 같은 화면 안에서 여러 그래프를 나눠 그리는 방식이었다.
기초 분석 수업에서는 정량·정성 데이터와 빅데이터의 5V를 정리한 뒤, 난수로 만든 키 데이터를 사용했다. 실제 지역별 조사 자료가 아니라 10개 지역 이름을 컬럼으로 붙인 10×10 실습 데이터다.
서울 컬럼의 값 10개는 pd.cut()으로 구간을 나눴다.
df_class = pd.cut(
df["서울"],
bins=[140, 150, 160, 170, 180, 190]
)
출력된 (140, 150]은 140 초과, 150 이하 구간이었다. 구간별 개수를 집계해 도수분포표를 만들고 히스토그램으로도 확인했다.
상대도수 계산은 다시 볼 부분이 있다. 현재 코드는 서울 데이터 10개의 도수를 100으로 나누고 있다. 서울 내 분포를 구하려면 전체 100개가 아니라 집계 대상인 10개를 기준으로 나눠야 한다. 현재 상대도수의 합이 0.1인 것도 이 때문이다.
경기 컬럼에서는 평균을 구하고, 각 값에서 평균을 뺀 편차를 계산했다. 편차를 제곱한 값들의 평균으로 분산을 구하고 제곱근을 취해 표준편차를 구했다.
variance = gyeonggi_df["편차의 제곱"].mean()
variance ** 0.5
실습 결과는 평균 164.4, 분산 182.64, 표준편차 약 13.51이었다. 여기서는 편차 제곱의 합을 데이터 개수로 나누는 방식으로 계산했다.
오늘은 필요한 행을 고르고, 기준별로 묶고, 그래프와 통계량으로 확인하는 과정을 이어서 해봤다. 특히 비율을 구할 때는 어떤 데이터를 분모로 삼는지 먼저 확인해야 했다.
다음에는 상대도수 계산을 다시 확인하고, loc와 iloc의 선택 결과를 직접 비교하면서 복습하려고 한다.