Validation 데이터를 정리하다가, 또는 배치별 수율을 트렌드로 묶다가 "이거 엑셀로 하기엔 너무 반복적인데"라는 생각이 든 적이 있을 겁니다. 시험 결과 수백 건을 필터링하고, 배치마다 스펙 이탈 여부를 확인하고, 그 결과를 그래프로 옮기는 작업은 엑셀로도 되긴 하지만 손이 많이 갑니다. 이럴 때 등장하는 것이 파이썬(Python)과 그 위에서 돌아가는 판다스(Pandas), 넘파이(NumPy), 맷플롯립(Matplotlib)입니다.
문제는 이 넷의 이름과 역할이 뒤섞여서 다가온다는 점입니다. 이 글은 코딩을 전혀 해본 적 없지만 엑셀은 매일 쓰는 QA/CMC 실무자를 기준으로, 네 가지 도구가 각각 무엇을 담당하는지와 실무에서 자주 쓰는 핵심 용어(함수)를 정리합니다.
왜 엑셀에 익숙한 사람도 이 도구들을 알아야 할까
엑셀은 수십, 수백 행 정도의 데이터를 다루는 데는 충분합니다. 하지만 배치가 수천 건 쌓이거나, 매달 같은 형태의 트렌드 보고서를 반복해서 만들어야 하거나, 여러 파일에 흩어진 시험 결과를 한 번에 모아 분석해야 하는 상황에서는 엑셀의 수작업 방식이 병목이 됩니다. 파이썬과 그 라이브러리들은 이 반복 작업을 코드 몇 줄로 자동화하고, 사람이 놓치기 쉬운 필터링·집계 실수를 줄여줍니다. 처음부터 모든 업무를 코드로 옮길 필요는 없고, 반복이 많은 작업부터 하나씩 옮겨보는 정도로 시작하면 충분합니다.
라이브러리란 결국 무엇인가
엑셀에는 이미 만들어진 함수(AVERAGE, VLOOKUP, SUMIF)가 있어서, 그 계산 로직을 처음부터 짤 필요가 없습니다. 파이썬의 "라이브러리"도 정확히 같은 개념입니다. 누군가 미리 짜서 이름을 붙여둔 함수들의 묶음이며, 우리는 그 이름만 알면 가져다 쓸 수 있습니다. 다만 엑셀은 함수가 하나의 프로그램 안에 다 들어있는 반면, 파이썬은 목적에 따라 함수 묶음이 여러 라이브러리로 나뉘어 있다는 점이 다릅니다.
| 도구 | 엑셀에 비유하면 | 주로 담당하는 일 |
|---|---|---|
| 파이썬(Python) | 엑셀이라는 프로그램 자체(문법 규칙) | 변수 저장, 조건 판단, 반복 실행 등 기본 규칙 |
| 판다스(Pandas) | 워크시트·표 조작 기능 전체 | 표 형태 데이터 불러오기, 필터링, 정렬, 집계 |
| 넘파이(NumPy) | 대량 숫자 계산용 수식 엔진 | 수천~수백만 개 숫자의 통계·행렬 연산 |
| 맷플롯립(Matplotlib) | 차트 삽입 기능 | 선그래프, 막대그래프, 관리도 형태 시각화 |
파이썬 기초 문법, 딱 4가지만 알면 됩니다
판다스나 넘파이의 함수를 쓰려면 최소한의 파이썬 문법이 필요합니다. 다행히 실무에서 자주 쓰는 규칙은 네 가지뿐입니다.
- 변수 — 값을 이름 붙은 상자에 저장합니다.
spec_upper = 105는 spec_upper라는 상자에 105를 저장하라는 뜻입니다. - 조건문 — "만약 ~라면"을 처리합니다.
if result > spec_upper:는 결과값이 상한 규격을 초과하면 다음 줄을 실행하라는 뜻입니다. - 반복문 — 같은 작업을 여러 번 반복시킵니다.
for batch in batch_list:는 배치 목록을 하나씩 꺼내며 같은 처리를 반복하라는 뜻입니다. - 함수 호출 — 라이브러리 안에 준비된 기능을 이름으로 꺼내 씁니다.
df.mean()처럼 점(.) 뒤에 함수 이름을 붙이는 형태가 가장 흔합니다.
이 네 가지만 눈에 익어도 판다스·넘파이 코드의 절반은 그대로 읽힙니다. 나머지는 매번 검색하면서 채워도 무방합니다.
판다스: 엑셀 작업을 코드로 옮기는 용어집
판다스는 표(DataFrame) 형태 데이터를 다루는 라이브러리로, 실무에서 엑셀로 하던 작업 대부분이 판다스 명령 한두 줄로 옮겨집니다. 평소 엑셀에서 하던 동작을 기준으로 매칭하면 익히기가 훨씬 수월합니다.
| 엑셀에서 하던 작업 | 판다스 명령 | 의미 |
|---|---|---|
| 파일 열기 | pd.read_excel('파일명.xlsx') | 엑셀 파일을 표 형태로 불러오기 |
| 위쪽 몇 줄만 확인 | df.head(5) | 상위 5개 행만 미리보기 |
| 데이터 > 필터 | df[df['결과'] >= 30] | 조건에 맞는 행만 골라내기 |
| 빈 셀 처리 | df.dropna() / df.fillna(값) | 빈칸이 있는 행 삭제 또는 값으로 채우기 |
| VLOOKUP | pd.merge(df1, df2, on='배치번호') | 공통 열 기준으로 두 표 합치기 |
| 데이터 > 정렬 | df.sort_values(by='시험일자') | 특정 열 기준 오름차순/내림차순 정렬 |
| =AVERAGE(), =SUM() | df['결과'].mean(), .sum() | 열 평균, 합계 구하기 |
| 삽입 > 피벗테이블 | df.pivot_table(index='부서', values='수율') | 기준 열별로 요약 집계 |
| 중복 항목 제거 | df.drop_duplicates() | 중복된 행을 하나만 남기고 삭제 |
이 표 하나만 옆에 두고 있어도, "엑셀에서 이거 하려면 판다스에서는 뭘 써야 하지?"라는 질문의 절반은 바로 답이 나옵니다.
넘파이: 숫자가 많아질 때 등장하는 계산 엔진
판다스가 표(행과 열이 섞인 데이터)를 다룬다면, 넘파이는 순수하게 숫자로만 이루어진 대량 데이터를 빠르게 계산할 때 씁니다. 예를 들어 한 시험법의 측정값 수백 개를 한꺼번에 통계 처리하거나, 관리도용 상한·하한선을 계산할 때 유용합니다. 판다스 표와 마찬가지로, 엑셀에서 하던 계산을 기준으로 매칭하면 이해가 빠릅니다.
| 엑셀에서 하던 작업 | 넘파이 명령 | 의미 |
|---|---|---|
| 숫자 범위 선택 | np.array([...]) | 숫자 목록을 계산에 최적화된 배열로 변환 |
| =AVERAGE() | np.mean(arr) | 평균 계산 |
| =STDEV.S() | np.std(arr, ddof=1) | 표본 표준편차 계산 (관리한계 산출에 자주 사용) |
| =MAX(), =MIN() | np.max(arr), np.min(arr) | 최댓값, 최솟값 확인 |
| =IF() | np.where(조건, 참일때값, 거짓일때값) | 조건에 따라 값을 한 번에 바꾸기 (예: 스펙 초과 시 "OOS", 아니면 "정상"으로 표시) |
실무에서는 넘파이를 단독으로 쓰기보다, 판다스로 표를 정리한 뒤 그 안의 숫자 열에 넘파이 통계 함수를 적용하는 방식으로 함께 쓰는 경우가 대부분입니다.
맷플롯립: 결과를 눈에 보이는 그래프로
판다스와 넘파이로 정리한 숫자를 트렌드 차트나 관리도 형태로 눈에 보이게 그리는 도구입니다. 마찬가지로 엑셀 차트 기능과 매칭해서 보면 낯설지 않습니다.
| 엑셀에서 하던 작업 | 맷플롯립 명령 | 의미 |
|---|---|---|
| 삽입 > 차트 > 꺾은선형 | plt.plot(x, y) | 시간에 따른 변화(트렌드)를 선그래프로 표시 |
| 삽입 > 차트 > 세로 막대형 | plt.bar(x, y) | 배치별, 부서별 값 비교 |
| 삽입 > 차트 > 분산형 | plt.scatter(x, y) | 두 변수 간 상관관계를 점으로 표시 |
| 차트에 도형(직선) 삽입 | plt.axhline(y=105) | 스펙 상한선 같은 기준선을 수평으로 그어주기 (관리도에서 자주 사용) |
| 차트 제목/축 제목 입력 | plt.title(), plt.xlabel(), plt.ylabel() | 제목과 축 이름 붙이기 |
| 다른 이름으로 저장(그림) | plt.savefig('파일명.png') | 완성된 그래프를 이미지 파일로 저장 (보고서 삽입용) |
한 가지 자주 겪는 문제는 한글이 깨져서 네모(□□□)로 표시되는 현상입니다. 아래 코드를 그래프를 그리기 전에 한 번 실행해두면 해결됩니다.
import matplotlib.pyplot as plt
plt.rc('font', family='Malgun Gothic') # 윈도우 기준, 맥은 'AppleGothic'
실전 예시: 시험 결과 데이터 하나로 세 가지 도구 이어 붙이기
실제로 배치별 시험 결과를 정리한다고 가정하면, 세 라이브러리는 아래와 같은 흐름으로 이어집니다.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 1. 판다스: 엑셀 파일 불러오고 스펙 초과 배치만 필터링
df = pd.read_excel('배치별_시험결과.xlsx')
oos = df[df['결과'] > df['상한규격']]
# 2. 넘파이: 전체 결과값의 평균과 표준편차 계산
mean_val = np.mean(df['결과'])
std_val = np.std(df['결과'])
# 3. 맷플롯립: 트렌드 차트에 평균선과 스펙 상한선 함께 표시
plt.plot(df['시험일자'], df['결과'])
plt.axhline(y=mean_val, color='green', linestyle='--')
plt.axhline(y=df['상한규격'].iloc[0], color='red', linestyle='--')
plt.title('배치별 결과 트렌드')
plt.savefig('트렌드_결과.png')
판다스가 표를 정리하고, 넘파이가 숫자를 계산하고, 맷플롯립이 그 결과를 그림으로 옮기는 역할 분담이 코드 안에 그대로 드러납니다.
한 걸음 더: 실무에서 자주 쓰는 코드 6가지
앞서 다룬 기본기에 아래 여섯 가지를 더하면, CMC/QA 실무에서 마주치는 상황 대부분을 코드로 커버할 수 있습니다.
1. %RSD(변동계수)로 정밀도 확인하기
분석법 정밀도(Precision) 평가에서 거의 빠지지 않는 계산입니다. 표준편차를 평균으로 나눈 값에 100을 곱하면 됩니다. 이때 ddof=1을 반드시 지정해야 하는데, 이는 표본 표준편차(n-1로 나누는 방식)를 쓰겠다는 의미입니다. 지정하지 않으면 넘파이는 기본적으로 모표준편차(n으로 나누는 방식)를 계산하므로, 밸리데이션 보고서에 쓰는 %RSD와 값이 미세하게 달라질 수 있습니다.
import numpy as np
results = np.array([98.2, 99.1, 98.7, 99.5, 98.9])
rsd = (np.std(results, ddof=1) / np.mean(results)) * 100
print(f"%RSD: {rsd:.2f}%")
2. 규격 자동 판정: Pass/Fail 열 만들기
앞서 소개한 np.where를 응용하면 상한·하한 규격을 동시에 만족하는지 판정해서 새로운 열로 바로 추가할 수 있습니다. 조건 두 개를 &(그리고)로 묶을 때는 각 조건을 반드시 괄호로 감싸야 오류가 나지 않습니다.
df['판정'] = np.where(
(df['결과'] >= df['하한규격']) & (df['결과'] <= df['상한규격']),
'Pass', 'Fail'
)
3. 여러 엑셀 파일 한 번에 합치기
월별로 나뉜 배치 데이터 파일을 매번 손으로 복사·붙여넣기 하는 대신, 폴더 안의 파일을 한 번에 불러와 하나의 표로 합칠 수 있습니다. glob은 폴더 안에서 조건에 맞는 파일 이름을 모두 찾아주는 표준 라이브러리이고, pd.concat은 여러 표를 위아래로 이어 붙입니다.
import glob
import pandas as pd
file_list = glob.glob('배치데이터/*.xlsx')
df_list = [pd.read_excel(f) for f in file_list]
df_all = pd.concat(df_list, ignore_index=True)
이때 각 파일의 열 이름과 순서가 서로 같아야 오류 없이 합쳐진다는 점만 주의하면 됩니다.
4. 분석자별·장비별 통계 요약표 만들기
피벗테이블이 값을 한 가지 방식으로만 요약한다면, groupby().agg()는 평균·표준편차·건수처럼 여러 통계를 한 번에 뽑아낼 수 있어 분석자 간 편차나 장비 간 편차를 점검할 때 유용합니다.
summary = df.groupby(['분석자', '장비']).agg(
평균=('결과', 'mean'),
표준편차=('결과', 'std'),
건수=('결과', 'count')
)
print(summary)
5. 결과를 다시 엑셀로 저장하기
지금까지는 read_excel로 불러오기만 했는데, 정리·계산이 끝난 표는 to_excel로 다시 파일로 내보낼 수 있습니다. index=False를 빼먹으면 판다스가 자동으로 매긴 행 번호까지 별도 열로 저장되므로, 보고서용 파일을 만들 때는 꼭 함께 써주는 것이 좋습니다.
df_all.to_excel('통합_결과.xlsx', index=False)
6. 날짜 구간으로 데이터 필터링하기
안정성 시험(Stability)처럼 특정 기간의 데이터만 따로 뽑아야 하는 경우, 날짜 열을 먼저 진짜 날짜 형식으로 변환한 뒤 구간을 지정해 필터링합니다. 엑셀에서 날짜가 텍스트로 인식되어 필터가 꼬이는 문제와 비슷한 원리로, pd.to_datetime을 거치지 않으면 날짜 비교가 정확하게 되지 않을 수 있습니다.
df['시험일자'] = pd.to_datetime(df['시험일자'])
stability_3m = df[
(df['시험일자'] >= '2026-01-01') & (df['시험일자'] <= '2026-03-31')
]
처음 시작할 때 흔히 겪는 어려움
가장 먼저 부딪히는 벽은 "문법을 다 외워야 하나"라는 부담입니다. 외울 필요는 없습니다. 현업 개발자들도 필요할 때마다 공식 문서나 검색을 통해 함수 이름과 사용법을 확인하며 코드를 씁니다. 중요한 것은 "이런 기능이 존재한다"는 사실을 기억해두는 것이고, 정확한 문법은 그때그때 찾아 쓰면 됩니다. 또한 처음에는 엑셀로 5분이면 끝날 작업을 코드로 옮기려다 오히려 시간이 더 걸리는 경우가 많은데, 이는 반복 작업이 쌓였을 때 진가를 발휘하는 도구이기 때문입니다. 한 번 만든 코드는 다음 달, 다음 배치에도 그대로 재사용할 수 있다는 점에서 투자한 시간을 되찾게 됩니다.
FAQ
Q1. 엑셀을 잘 쓰면 굳이 코딩을 배울 필요가 있나요?
단발성 작업이거나 데이터가 적다면 엑셀만으로도 충분합니다. 다만 같은 형식의 보고서를 매달 반복해서 만들거나, 여러 파일에 흩어진 데이터를 자주 통합해야 하는 업무라면 코드로 옮겼을 때 시간 절감 효과가 큽니다.
Q2. 판다스, 넘파이, 맷플롯립을 꼭 순서대로 다 배워야 하나요?
실무에서는 판다스부터 익히는 것을 권합니다. 표 형태 데이터를 다루는 빈도가 가장 높기 때문입니다. 통계 계산이 복잡해지면 넘파이를, 결과를 시각 자료로 보고해야 하면 맷플롯립을 그때그때 필요한 만큼 익히는 방식이 부담이 적습니다.
Q3. 코드에서 오류가 나면 어떻게 해결하나요?
오류 메시지를 그대로 검색하거나 AI에게 오류 문구와 코드를 함께 보여주고 원인을 물어보는 방법이 가장 빠릅니다. 판다스와 넘파이는 사용자가 매우 많은 라이브러리라, 대부분의 오류는 이미 누군가 겪고 해결한 사례가 있습니다.
Q4. 데이터가 몇 건 이상이어야 코드로 처리하는 의미가 있나요?
정해진 기준은 없지만, 같은 필터링·집계 작업을 매번 손으로 반복해야 하거나 데이터가 수백 행을 넘어가는 시점부터 체감 효과가 커지는 경우가 많습니다. 반대로 한 번만 확인하고 끝나는 작업이라면 엑셀이 더 빠를 수 있습니다.
참고문헌
- pandas 공식 문서 — DataFrame 기본 개념과 함수 목록: https://pandas.pydata.org/docs/
- NumPy 공식 문서 — 배열 생성 및 통계 함수 안내: https://numpy.org/doc/stable/
- Matplotlib 공식 문서 — pyplot 기본 사용법: https://matplotlib.org/stable/tutorials/pyplot.html
- Python 공식 문서 — 변수, 조건문, 반복문 등 기본 문법: https://docs.python.org/3/tutorial/
결국 파이썬과 세 라이브러리의 관계는 엑셀과 그 안의 기능들의 관계와 크게 다르지 않습니다. 파이썬이 기본 문법이라면, 판다스는 표를 다루는 함수 묶음, 넘파이는 대량 숫자 계산 함수 묶음, 맷플롯립은 그 결과를 그림으로 옮기는 함수 묶음입니다. 처음부터 전체를 마스터하려 하기보다, 지금 손으로 반복하고 있는 엑셀 작업 하나를 골라 판다스 명령 한두 줄로 옮겨보는 것이 가장 빠른 시작입니다.
댓글
댓글 쓰기