AI로 데이터 분석 자동화하기 - pandas + GPT API 실전 가이드
2026년 4월 기준 | AI 개발 가이드
이 글에서 다루는 것: pandas로 데이터를 처리하고 GPT API에 넘겨서 자동으로 인사이트를 뽑아내는 파이프라인을 만듭니다. 매출 데이터 분석, 이상치 탐지, 자연어 보고서 생성, 심지어 "데이터에 질문하기" 기능까지 구현합니다. 엑셀만 만지던 팀에 이 시스템을 적용했을 때의 실제 반응과 효과도 공유합니다.
왜 pandas + GPT인가
데이터 분석은 크게 두 단계입니다. 1) 데이터를 가공/계산하는 것과 2) 결과를 해석해서 의미를 뽑아내는 것. pandas는 1번을 엄청나게 잘합니다. GPT는 2번을 엄청나게 잘합니다. 합치면 무슨 일이 벌어질까요?
기존에 데이터 분석 업무는 이랬습니다:
① 엑셀에서 데이터 정리 (30분)
② 피벗 테이블, 차트 만들기 (30분)
③ 숫자를 보고 의미 해석 (30분)
④ 보고서 작성 (1시간)
합계: 약 2.5시간
① 스크립트 실행 (10초)
② pandas가 데이터 가공 + 통계 산출 (2초)
③ GPT가 결과 해석 + 보고서 작성 (15초)
④ 사람이 검토/수정 (10분)
합계: 약 11분
과장이 아닙니다. 실제로 우리 팀에서 매주 만들던 주간 매출 보고서가 2시간에서 10분으로 줄었습니다. 물론 처음 스크립트를 만드는 데 2~3시간 걸렸지만, 매주 반복하는 업무니까 두 번째 주부터 바로 이득입니다.
환경 설정
# 필요한 패키지
pip install pandas openai openpyxl matplotlib
import pandas as pd import openai import json from openai import OpenAI client = OpenAI() # OPENAI_API_KEY 환경변수 필요
기본: CSV 데이터를 AI로 분석하기
가장 간단한 형태부터 시작합니다. CSV를 읽고, pandas로 기본 통계를 내고, GPT에 해석을 맡기는 겁니다.
def analyze_csv_with_ai(csv_path): """CSV 파일을 읽고 AI로 분석""" # Step 1: pandas로 데이터 읽기 df = pd.read_csv(csv_path) # Step 2: 기본 통계 산출 stats = { "행 수": len(df), "컬럼": list(df.columns), "데이터 타입": df.dtypes.to_dict(), "기본 통계": df.describe().to_dict(), "결측치": df.isnull().sum().to_dict(), "상위 5행": df.head().to_dict(), } # 숫자형 컬럼 상관관계 numeric_cols = df.select_dtypes(include=['number']).columns if len(numeric_cols) >= 2: stats["상관관계"] = df[numeric_cols].corr().to_dict() # Step 3: GPT에게 해석 요청 response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": """데이터 분석 전문가입니다. 주어진 통계 데이터를 분석하고, 비전문가도 이해할 수 있는 인사이트를 제공하세요. 형식: 1. 데이터 개요 (한 줄 요약) 2. 주요 발견 3-5개 3. 주의해야 할 점 4. 추천 추가 분석"""}, {"role": "user", "content": f"다음 데이터 통계를 분석해줘:\n{json.dumps(stats, default=str, ensure_ascii=False)}"} ], temperature=0.3 ) return response.choices[0].message.content # 사용 result = analyze_csv_with_ai("sales_2026_q1.csv") print(result)
이 코드를 회사 매출 데이터에 돌렸더니 이런 결과가 나왔습니다:
1. 데이터 개요: 1분기 매출 데이터 2,847건으로, 일평균 약 31건의 거래가 발생했습니다.
2. 주요 발견:
- 3월 매출이 1월 대비 34% 증가 → 뚜렷한 성장 추세
- "프리미엄" 카테고리의 객단가가 평균의 2.3배로 전체 매출의 41% 차지
- 주말 거래 건수가 평일의 62%이지만, 건당 금액은 18% 더 높음
- 결측치가 "할인코드" 컬럼에 67% → 대부분의 고객이 할인 없이 구매
3. 주의: "환불" 컬럼에 음수값 23건 존재, 데이터 정합성 확인 필요
4. 추천 추가 분석: 재구매율 분석, 카테고리별 시계열 분석, 할인 여부에 따른 객단가 비교
사람이 엑셀로 30분 걸려 뽑을 내용을 15초 만에 뽑았습니다. 특히 "환불 컬럼 음수값 23건"은 실제로 데이터 오류였는데, 사람 눈으로는 놓치기 쉬운 걸 잡아낸 겁니다.
자동 인사이트 추출기 만들기
기본 분석을 넘어서, 좀 더 구조화된 인사이트를 뽑아내는 시스템을 만들었습니다. 핵심은 pandas에서 다양한 분석을 미리 돌리고, 그 결과를 GPT에 한꺼번에 넘기는 겁니다.
class DataInsightExtractor: """데이터에서 자동으로 인사이트를 추출하는 클래스""" def __init__(self, df): self.df = df self.client = OpenAI() self.insights = {} def run_all_analyses(self): """pandas로 모든 분석 실행""" self.insights["basic_stats"] = self._basic_stats() self.insights["trends"] = self._time_trends() self.insights["segments"] = self._segment_analysis() self.insights["anomalies"] = self._detect_anomalies() return self def _basic_stats(self): """기본 통계""" return { "shape": self.df.shape, "describe": self.df.describe().to_dict(), "null_counts": self.df.isnull().sum().to_dict(), "unique_counts": {col: self.df[col].nunique() for col in self.df.select_dtypes(include=['object']).columns} } def _time_trends(self): """시계열 트렌드 분석""" date_cols = self.df.select_dtypes(include=['datetime64']).columns if len(date_cols) == 0: # 날짜 형식 컬럼 자동 탐지 for col in self.df.columns: try: self.df[col] = pd.to_datetime(self.df[col]) date_cols = [col] break except: continue if len(date_cols) == 0: return {"message": "날짜 컬럼 없음"} date_col = date_cols[0] numeric_cols = self.df.select_dtypes(include=['number']).columns trends = {} for col in numeric_cols[:3]: # 상위 3개 숫자 컬럼 monthly = self.df.groupby(self.df[date_col].dt.to_period('M'))[col].agg(['sum', 'mean', 'count']) trends[col] = monthly.to_dict() return trends def _segment_analysis(self): """카테고리별 세그먼트 분석""" cat_cols = self.df.select_dtypes(include=['object']).columns num_cols = self.df.select_dtypes(include=['number']).columns segments = {} for cat in cat_cols[:2]: # 상위 2개 카테고리 컬럼 if self.df[cat].nunique() <= 20: # 카테고리가 너무 많으면 스킵 for num in num_cols[:2]: segments[f"{cat}_by_{num}"] = ( self.df.groupby(cat)[num] .agg(['mean', 'sum', 'count']) .to_dict() ) return segments def _detect_anomalies(self): """IQR 방식 이상치 탐지""" anomalies = {} for col in self.df.select_dtypes(include=['number']).columns: Q1 = self.df[col].quantile(0.25) Q3 = self.df[col].quantile(0.75) IQR = Q3 - Q1 lower = Q1 - 1.5 * IQR upper = Q3 + 1.5 * IQR outliers = self.df[(self.df[col] < lower) | (self.df[col] > upper)] if len(outliers) > 0: anomalies[col] = { "count": len(outliers), "percentage": round(len(outliers) / len(self.df) * 100, 2), "range": [float(lower), float(upper)], "examples": outliers[col].head(5).tolist() } return anomalies def get_ai_insights(self): """GPT에게 분석 결과 해석 요청""" response = self.client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": """시니어 데이터 분석가입니다. 주어진 분석 결과를 비즈니스 관점에서 해석하고 실행 가능한 인사이트를 제공합니다. 반드시 구체적인 숫자를 인용하면서 설명하세요."""}, {"role": "user", "content": json.dumps(self.insights, default=str, ensure_ascii=False)} ], temperature=0.3 ) return response.choices[0].message.content # 사용 df = pd.read_csv("sales_data.csv") extractor = DataInsightExtractor(df) extractor.run_all_analyses() insights = extractor.get_ai_insights() print(insights)
pandas가 미리 계산을 다 해놓으니까 GPT는 해석만 하면 됩니다. 이 구조가 중요합니다. GPT에게 원본 데이터를 통째로 보내면 토큰 비용이 폭증하고, 계산 실수도 합니다. 계산은 pandas, 해석은 GPT. 이 분업이 핵심입니다.
이상치 탐지 + AI 해석
이상치를 발견하는 것 자체는 pandas로 쉽게 합니다. 하지만 "왜 이상치인지", "어떻게 대응해야 하는지"는 GPT가 설명해줍니다.
def analyze_anomalies_with_context(df, target_col, context_cols): """이상치를 찾고 주변 데이터와 함께 AI에게 해석 요청""" # 이상치 탐지 Q1 = df[target_col].quantile(0.25) Q3 = df[target_col].quantile(0.75) IQR = Q3 - Q1 outliers = df[ (df[target_col] < Q1 - 1.5 * IQR) | (df[target_col] > Q3 + 1.5 * IQR) ] if outliers.empty: return "이상치가 발견되지 않았습니다." # 이상치 데이터와 정상 데이터 통계 비교 normal = df[~df.index.isin(outliers.index)] comparison = { "이상치 수": len(outliers), "전체 대비 비율": f"{len(outliers)/len(df)*100:.1f}%", "이상치 통계": outliers[context_cols + [target_col]].describe().to_dict(), "정상 데이터 통계": normal[context_cols + [target_col]].describe().to_dict(), "이상치 샘플 (상위 10건)": outliers[context_cols + [target_col]].head(10).to_dict() } response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": "데이터 품질 전문가입니다. 이상치의 원인을 추정하고 대응 방안을 제시합니다."}, {"role": "user", "content": f"""'{target_col}' 컬럼에서 이상치가 발견됐습니다. 분석 결과: {json.dumps(comparison, default=str, ensure_ascii=False)} 1. 이상치의 패턴이 있는지 분석해줘 2. 가능한 원인을 추정해줘 3. 데이터를 유지할지 제거할지 추천해줘 4. 추가로 확인해야 할 사항을 알려줘"""} ] ) return response.choices[0].message.content # 사용 result = analyze_anomalies_with_context( df, target_col="order_amount", context_cols=["category", "region", "customer_type"] ) print(result)
실제로 매출 데이터에서 이상치 분석을 돌렸더니, GPT가 "이상치 23건 중 19건이 '기업 고객' 카테고리에 집중되어 있고, 모두 월말에 발생했으므로 대량 구매 건으로 추정됩니다. 제거하지 말고 별도 세그먼트로 분리 분석을 권장합니다"라고 나왔습니다. 이 해석이 정확했습니다. 실제로 기업 고객의 월말 대량 주문이었습니다.
"데이터에 질문하기" 시스템
이게 가장 재미있는 부분입니다. 자연어로 질문하면 pandas 코드를 자동 생성해서 실행하고, 결과를 자연어로 답해주는 시스템입니다.
class DataQA: """자연어로 데이터에 질문하는 시스템""" def __init__(self, df, df_name="df"): self.df = df self.df_name = df_name self.client = OpenAI() self.history = [] def _get_schema(self): """데이터 스키마 정보 생성""" schema = f"DataFrame 이름: {self.df_name}\n" schema += f"행 수: {len(self.df)}\n" schema += "컬럼:\n" for col in self.df.columns: dtype = self.df[col].dtype sample = self.df[col].dropna().head(3).tolist() schema += f" - {col} ({dtype}): 예시 {sample}\n" return schema def ask(self, question): """자연어 질문 → pandas 코드 생성 → 실행 → 자연어 답변""" # Step 1: 질문을 pandas 코드로 변환 code_response = self.client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": f"""pandas 코드 생성기입니다. 데이터 스키마: {self._get_schema()} 규칙: - 변수명은 '{self.df_name}' 사용 - 결과를 'result' 변수에 저장 - pandas 코드만 출력, 설명 없음 - import문 불필요 (이미 import됨) - print문 불필요"""}, {"role": "user", "content": question} ], temperature=0 ) code = code_response.choices[0].message.content code = code.replace("```python", "").replace("```", "").strip() # Step 2: 코드 실행 try: local_vars = {self.df_name: self.df, "pd": pd} exec(code, {"pd": pd}, local_vars) result = local_vars.get("result", "결과 없음") except Exception as e: result = f"코드 실행 오류: {e}" # Step 3: 결과를 자연어로 변환 answer_response = self.client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": "데이터 분석 결과를 친절하게 설명합니다."}, {"role": "user", "content": f"질문: {question}\n실행 코드:\n{code}\n결과:\n{result}"} ] ) answer = answer_response.choices[0].message.content self.history.append({"question": question, "code": code, "answer": answer}) print(f"Q: {question}") print(f"[생성된 코드]\n{code}") print(f"\nA: {answer}\n") return answer # 사용 df = pd.read_csv("sales_data.csv") qa = DataQA(df) qa.ask("가장 매출이 높은 카테고리는?") qa.ask("월별 매출 추이를 보여줘") qa.ask("서울 지역의 평균 주문금액은?") qa.ask("재구매 고객 비율은 얼마야?")
이 시스템을 비개발자 팀원에게 줬더니 반응이 폭발적이었습니다. "매출 상위 10개 제품 알려줘", "지난달 대비 이번 달 성장률은?" 같은 질문을 채팅하듯 입력하면 바로 답이 나오니까요. 엑셀 피벗 테이블을 30분 만지던 작업이 10초로 줄었습니다.
자동 보고서 생성기
모든 분석을 통합해서 정해진 형식의 보고서를 자동으로 만드는 시스템입니다.
def generate_weekly_report(csv_path, report_title="주간 매출 보고서"): """CSV 데이터로 주간 보고서 자동 생성""" df = pd.read_csv(csv_path) df['date'] = pd.to_datetime(df['date']) # pandas로 핵심 지표 계산 metrics = { "총 매출": f"{df['amount'].sum():,.0f}원", "총 주문 수": f"{len(df):,}건", "평균 주문 금액": f"{df['amount'].mean():,.0f}원", "일평균 매출": f"{df.groupby('date')['amount'].sum().mean():,.0f}원", "최고 매출일": str(df.groupby('date')['amount'].sum().idxmax().date()), "카테고리별 매출": df.groupby('category')['amount'].sum().to_dict(), "요일별 매출": df.groupby(df['date'].dt.day_name())['amount'].sum().to_dict(), "상위 10개 제품": df.groupby('product')['amount'].sum().nlargest(10).to_dict(), } # GPT로 보고서 작성 response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": f"""비즈니스 보고서 작성 전문가입니다. 아래 형식으로 '{report_title}'을 작성하세요: # {report_title} ## 1. 핵심 요약 (Executive Summary) 3줄 이내로 이번 주 성과를 요약 ## 2. 주요 지표 표 형식으로 핵심 KPI 정리 ## 3. 카테고리별 분석 각 카테고리의 성과와 특이사항 ## 4. 트렌드 분석 이전 대비 변화와 패턴 ## 5. 액션 아이템 데이터에서 도출된 실행 가능한 제안 3-5개"""}, {"role": "user", "content": json.dumps(metrics, default=str, ensure_ascii=False)} ], temperature=0.3 ) report = response.choices[0].message.content # 마크다운 파일로 저장 from datetime import datetime filename = f"report_{datetime.now():%Y%m%d}.md" with open(filename, "w", encoding="utf-8") as f: f.write(report) print(f"보고서 생성 완료: {filename}") return report # 실행 report = generate_weekly_report("this_week_sales.csv") print(report)
성능 벤치마크와 비용
실제 데이터로 측정한 결과입니다.
| 작업 | 데이터 크기 | pandas 처리 | GPT 분석 | 비용 |
|---|---|---|---|---|
| 기본 CSV 분석 | 1,000행 | 0.3초 | 8초 | $0.02 |
| 인사이트 추출 | 5,000행 | 1.2초 | 15초 | $0.05 |
| 주간 보고서 생성 | 3,000행 | 0.8초 | 20초 | $0.04 |
| 데이터 Q&A (1회) | 10,000행 | 0.1초 | 5초 | $0.01 |
하루에 보고서 1개 + Q&A 20회를 사용한다고 가정하면 월 비용은 약 $8입니다. 데이터 분석가 인건비와 비교하면 이건 반올림 오차 수준입니다.
실무 적용 팁
3개월간 실무에 적용하면서 배운 것들입니다.
1. GPT에게 원본 데이터를 통째로 보내지 마세요. pandas로 계산한 결과만 보내세요. 1만 행짜리 CSV를 통째로 보내면 토큰 비용이 $1 이상이고, 어차피 GPT는 계산을 잘 못합니다. pandas가 계산하고, GPT는 해석만.
2. 프롬프트에 출력 형식을 명확하게 지정하세요. "분석해줘"보다 "3가지 핵심 인사이트를 각각 1줄로 정리하고, 각 인사이트에 근거 숫자를 반드시 포함해줘"가 10배 좋은 결과를 냅니다.
3. 반복 작업은 클래스로 만들어두세요. 위의 DataInsightExtractor처럼 한 번 만들어두면 데이터만 바꿔서 재사용할 수 있습니다. 매주/매월 보고서를 만드는 작업에 특히 유용합니다.
4. temperature를 낮추세요. 데이터 분석에서는 창의적인 답변이 아니라 정확한 답변이 필요합니다. temperature=0.3 이하를 추천합니다.
5. 결과를 사람이 반드시 검증하세요. GPT가 가끔 그럴듯하지만 틀린 해석을 합니다. 특히 인과관계를 상관관계로 혼동하는 경우가 있습니다. AI 분석은 "초안"이고, 최종 판단은 사람이 해야 합니다.
핵심 정리
- 핵심 원칙: 계산은 pandas, 해석은 GPT - 이 분업이 비용과 정확도 모두 최적
- 기본 분석: CSV → pandas 통계 → GPT 해석 파이프라인 (10초, $0.02)
- 데이터 Q&A: 자연어 질문 → pandas 코드 자동 생성 → 실행 → 자연어 답변
- 자동 보고서: 매주/매월 반복되는 보고서를 스크립트 한 번으로 생성
- 비용: 일상적 사용 기준 월 $8 이하 (GPT-4o 기준)
- 주의: AI 분석은 초안, 최종 판단은 반드시 사람이
'AI 개발 가이드' 카테고리의 다른 글
| FastAPI + LLM으로 나만의 AI API 서버 만들기 (0) | 2026.04.12 |
|---|---|
| Docker로 AI 개발 환경 한 방에 세팅하기 - GPU 포함 완전 가이드 (0) | 2026.04.12 |
| Streamlit으로 AI 웹앱 30분 만에 배포하기 (0) | 2026.04.09 |
| Claude Code CLI로 프로젝트 자동화하기 - 실전 워크플로우 (0) | 2026.04.09 |
| AI 코드 리뷰 자동화 - GitHub Actions + Claude API로 PR 자동 리뷰 (0) | 2026.04.06 |