[학습 일기 #17] 데이터분석 및 시각화 1일차

Ariel_Jeong·2026년 1월 8일

[학습 일기 시리즈]

목록 보기
17/44

오늘은 데이터분석 및 시각화 수업 1일차로서
데이터 분석을 하기 위해 알아야 할 기본 개념들을 정리하는 시간이었다.

오늘 배운 데이터 타입에 대한 간략한 정리와 Pandas 기본 문법들에 대해 정리하고
과제를 하며 깨달은 점을 남겨보려고 한다.


* 예시 코드 및 과제 내용의 출처는 오즈코딩스쿨이다.



1. 데이터 타입

데이터 타입의 분류를 나누자면 아래와 같이 정리할 수 있다.

[데이터 타입]
├─ [숫자형, Numerical Data] : 산술 연산(더하기, 빼기, 평균 등)이 가능한 데이터
│   │
│   ├─ [연속형, Continuous] : 소수점 값이 의미를 가짐
│   │   └─ 예: 키, 몸무게, 온도
│   │
│   └─ [이산형, Discrete] : 정수 값만 존재
│       └─ 예: 환자 수, 방문 횟수
│
│
└─ [범주형, Categorical Data] :산술 연산이 의미가 없는 데이터
    │
    ├─ [순서형, Ordinal] : 범주 간 명확한 순서 or 등급이 있음
    │   └─ 예: 등급, 만족도
    │
    └─ [명목형, Nominal] : 범주 간 순서 or 서열이 없음
        └─ 예: 성별, 혈액형

1.1. 숫자형 vs. 범주형 특징 비교

✔ 숫자형의 특징

  • 평균, 중간값 계산 가능
  • 대소 비교 의미 있음
  • 히스토그램, 산점도 등으로 시각화
  • 통계적 검정 적용 가능

✔ 범주형의 특징

  • 평균 계산 불가능
  • 빈도, 비율 분석 중심
  • 막대그래프, 파이차트로 시각화
  • 카이제곱 검정 등 적용(빈도수 분포 차이 계산해서 의미가 있는지 판별)

1.2. 연속형 vs. 이산형 특징 비교

✔ 연속형의 특징

  • 소수점 값 존재
  • 구간별 분포 분석
  • 정규분포 등 연속 확률분포 적용
  • 회귀분석에 적합

✔ 이산형의 특징

  • 정수값만 존재
  • 카운트 데이터가 대표적
  • 포아송 분포 등 이산 확률분포 적용
  • 횟수, 개수 분석에 적합

1.2. 순서형 vs. 명목형 특징 비교

✔ 순서형의 특징

  • 범주 간 순서 명확
  • 중간값, 백분위수 계산 가능
  • 순위 기반 분석 방법 적용
  • 스피어만 상관계수 등 사용

✔ 순서형의 특징

  • 범주 간 순서 없음
  • 빈도 분석이 주요 분석법
  • 더미변수로 변환하여 분석
  • 카이제곱 검정 적용

데이터 타입을 올바르게 파악하고 분석을 해야 정확한 분석 결과를 얻을 수 있기 때문에
데이터 타입 개념을 정확히 알고 넘어가야 한다.



2. Pandas의 시작

Pandas는 데이터 분석에 주로 사용되는 Python의 핵심 라이브러리로서
Numpy가 연산에 최적화된 라이브러리라면 Pandas는 좀 더 확장된 기능을 가진
숫자, 문자, 날짜 등 혼합된 데이터 처리도 가능한 아주 유연한 라이브러리이다.

오늘은 데이터 구조를 생성하는 방법, CSV파일 읽고/쓰는 방법, 인덱싱과 슬라이싱 등
기본 문법들을 정리하고, 과제 내용을 분석해보겠다.


2.1. 데이터 구조 생성하기

2.1.1. Series

Series1차원 배열이며, 인덱스(라벨)와 값의 쌍으로 구성된다.
엑셀로 보자면 하나의 '열'을 선택했을 때, 이를 Series라고 할 수 있다.

Series를 생성하는 기본 문법은 아래와 같다.

pd.Series(넣고자 하는 데이터 리스트, index=라벨 목록)    # 이 때 Series의 첫 글자는 대문자를 지켜줘야 한다.

만약 index를 지정해주지 않는다면, 자동으로 0, 1, 2, ... 로 지정될 것이다.

2.1.2. DataFrame

DataFrame2차원 표 형태이며, 행(index)과 열(columns)로 구성된다.
생긴 형태가 엑셀 스프레드시트와 동일하다.
또한 한편으로는 여러 개의 Series를 모은 것이 DataFrame이라고 할 수 있다.

DataFrame을 생성하는 기본 문법은 아래와 같다.

# DataFrame 생성용 공통 변수
patient_names = ['김철수', '이영희', '박민수', '최지은']
columns = ['나이', '혈압', '혈당']

# method 1. 딕셔너리로 생성하기 - 컬럼 중심 데이터
dict = {
    '나이': [45, 67, 32, 29],      # 열 단위로 데이터 구성
    '혈압': [120, 140, 110, 115],
    '혈당': [95, 180, 88, 92]
}
df1 = pd.DataFrame(patient_dict, index=patient_names) 

# method 2. 리스트 in 리스트로 생성 - 행별 리스트
patient_records = [
    [45, 120, 95],    # 김철수 (행)
    [67, 140, 180],   # 이영희
    [32, 110, 88],    # 박민수
    [29, 115, 92]     # 최지은
]
df2 = pd.DataFrame(patient_records, index=patient_names, columns=columns)

처음에 수업을 들을 땐 1번 방법이 더 편해보였는데,
이후 문법들이 쌓이면서 2번 방법으로 생성 연습을 했으면
인덱싱과 슬라이싱을 덜 헷갈렸을 수도 있겠다는 생각이 들었다.


2.2. CSV 파일 읽기/쓰기

CSV 파일로 저장

health_df.to_csv('clinic_health_data.csv',  # 저장할 파일명(하위 폴더에 저장할 땐 경로도 기입 필요)
                 index=False,  # 행 번호(인덱스)는 저장하지 않음
                 encoding='utf-8-sig')  

CSV 파일 불러오기

df = pd.read_csv('clinic_health_data.csv')  # CSV 파일을 DataFrame으로 불러오기
df.head(3)  # 처음 3행만 출력하여 데이터 구조 확인. 빈 괄호로 사용 시 기본값 5줄

2.3. 데이터 탐색용 문법

  • len(df): 행 갯수
  • df.head(n): 처음 n행(지정 안하면 기본 5)
  • df.tail(n): 마지막 n행(지정 안하면 기본 5)
  • df.info(): 전반적 정보(컬럼별 타입, 결측치 개수, 메모리 사용량 등 종합 정보)
  • df.shape: 배열의 형태 (행, 열 개수) 튜플 형태 반환
  • ndim: 배열의 차원 수 - 벡터(1차원)인지 행렬(2차원)인지 구분
  • df.dtypes: 각 컬럼의 데이터 타입 확인
  • df.size: 전체 요소 개수 - 총 데이터 포인트 수 파악

2.4. 통계용 메소드

  • df.describe(): 기본 통계량(count, mean, std, min, 25%, 50%, 75%, max 값 출력)
  • df['컬럼명'].value_counts(): 범주형 데이터의 각 값별 빈도수 계산

2.5. 인덱싱과 슬라이싱

2.5.1. 컬럼 선택 문법

  • 단일 컬럼: df['컬럼명'] → Series 반환
  • 복수 컬럼: df[['컬럼1', '컬럼2']] → DataFrame 반환

2.5.2. iloc vs. loc

구분ilocloc
기준위치(숫자)라벨(문자열) or 인덱스 번호
인덱스0, 1, 2...0, 1, 2... 또는 'P001', 'P002'...
슬라이싱끝 미포함 (0:3 = 0,1,2)끝 포함 ('A':'C' = A,B,C)
사용법df.iloc[0] * 뒤에서 접근(음수)도 가능df.loc['환자A']
장점위치가 명확의미가 직관적 * bool mask 활용 가능
단점순서 변경시 위험라벨이 있어야 함
# iloc 문법
df.iloc[행위치, 열위치] -> 단일 데이터
df.iloc[행범위, 열범위] -> 다중 데이터
# loc 문법
df.loc[행라벨, 열라벨] -> 단일 데이터
df.loc[행범위, 열범위] -> 다중 데이터
df.loc[조건, 열라벨] -> 조건부 필터링

cf) 복합 조건 연산자의 경우, 아래의 기호를 사용하고 각 조건을 괄호로 묶어야 한다.

  • &: AND
  • |: OR
  • ~: NOT

2.6. 컬럼 추가/수정

컬럼 추가

  • df['새 컬럼'] = 값: 단일 컬럼 추가
  • df[['새 컬럼1'], ['새 컬럼2']] = [값1, 값2]: 다중 컬럼 추가
  • df['새 컬럼'] = df['기존 컬럼1'] + df['기존 컬럼2']: 계산 결과 할당
  • df.loc[조건, '새 컬럼'] = 값: 조건부 할당
  • df['새 컬럼'] = 조건: 조건 결과 계산하여 bool값으로 추가

컬럼 수정

  • df['컬럼']: 일괄 수정
  • df.loc[조건, 컬럼]: 조건을 만족하는 행의 컬럼값을 선별적으로 수정
  • df.loc[조건, [컬럼1, 컬럼2]] = [값1, 값2]: 조건을 기준으로 여러 컬럼의 값을 한 번에 수정

2.7. 행 추가/수정

행 추가(반드시 컬럼수와 순서에 맞춰 추가할 정보를 작성해야 한다)

  • df.loc[len(df)] = ['추가할 정보']: 인덱스 번호로 행 추가
  • df.loc['인덱스명'] = ['추가할 정보']: 인덱스명으로 행 추가
  • 결과 데이터프레임 = pd.concat([기존 df, 새 df], ignore_index=True): 여러 행 한번에 추가(* ignore_index=True를 작성하지 않으면, 기본값(False)으로 적용되어 인덱스 중복이 발생될 수 있다)
    cf) axis=0(기본값): 행 방향 연결, axis=1: 열 방향 연결

행 수정

  • .loc[라벨명, 컬럼명]으로 접근해서 값 재할당 해주면 됨

2.8. 데이터 삭제

  • .drop('라벨명' or '컬럼명', axis=0(기본값. 행 삭제) or 1(열 삭제), inplace=False(기본값. 원본 유지) or True(원본 수정))
    (* 여러 개를 삭제하고 싶으면 []로 묶기!)
  • .drop(columns=df.columns[컬럼번호]): 컬럼 번호 기준 삭제
  • .drop(df.index[인덱스번호]): 인덱스 번호 기준 삭제
  • .drop(df[조건].index): 조건에 부합하는 행의 인덱스 번호로 삭제
  • .drop(index=df.index[인덱스번호], columns=['컬럼명']): 행과 컬럼 동시 삭제


3. Pandas 1일차 과제

3.1. 요구사항 및 출력 형식


[캡쳐 1-1. Pandas 1일차 과제 요구사항 및 출력 형식]


3.2. 1, 2번 미션 코드 비교


[캡쳐 1-2. 1, 2번 미션 코드 비교]

1) 특정 열을 인덱스로 설정

문법이 생각나지 않아 다시 수업 자료를 확인하였다.

정답 코드와 비교해 보니
DataFrame 생성 기본 문법에 .set_index('컬럼명')의 형태로 바로 이어서도 사용 가능하단걸 깨달았다.

2) 환자수 및 컬럼 수

.shape을 사용하고 인덱스 번호로 꺼내 쓸 필요 없이 len()을 활용하면 더욱 간단하다.
len()을 활용할 생각을 못했다는 것은 아직 구조 개념이 온전하게 정리되지 않았다는 의미일 것이다.

3) 나이, 혈압 컬럼만 선택하여 전체 조회

df['컬럼명']으로 데이터를 추출하는 것과 .loc[]을 사용하여 추출하는 것의 차이에 대한 개념이
아직 확실히 잡히지 않아 오류를 많이 겪었다.
특정 컬럼명을 사용하여 해당하는 모든 데이터를 가져올 때는
굳이 .loc[]을 사용하지 않는 것이 간편하다.

3.3. 3 ~ 5번 미션 코드 비교


[캡쳐 1-3. 3~5번 미션 코드 비교]

1) 아직도 불필요하게 변수 선언을 하고 재사용하는 자신을 발견했다.

2) 조건에 맞게 새 컬럼 생성

문법이 아직 익숙지 않아 여러번 반복해서 작성해 봐야겠다.

profile
R&D 분야의 경험을 토대로 커리어 확장에 도전중인 개발꿈나무입니다.

0개의 댓글