데이터 분석 스킬
개요
이 스킬은 DuckDB(인프로세스 분석 SQL 엔진)를 사용하여 사용자가 업로드한 Excel/CSV 파일을 분석합니다. 스키마 검사, SQL 기반 질의, 통계 요약, 결과 내보내기를 단일 Python 스크립트를 통해 지원합니다.
핵심 기능
- Excel/CSV 파일 구조 검사 (시트, 컬럼, 타입, 행 수)
- 업로드된 데이터에 대한 임의 SQL 질의 실행
- 통계 요약 생성 (평균, 중앙값, 표준편차, 백분위수, null 개수)
- 다중 시트 Excel 통합 문서 지원 (각 시트가 테이블이 됨)
- 질의 결과를 CSV, JSON, Markdown으로 내보내기
- DuckDB의 컬럼형 엔진을 통한 대용량 파일 효율적 처리
워크플로우
1단계: 요구사항 이해
사용자가 데이터 파일을 업로드하고 분석을 요청하면 다음을 식별하세요:
- 파일 위치:
/mnt/user-data/uploads/아래 업로드된 Excel/CSV 파일 경로 - 분석 목표: 사용자가 원하는 인사이트 (요약, 필터링, 집계, 비교 등)
- 출력 형식: 결과 표시 방법 (표, CSV 내보내기, JSON 등)
/mnt/user-data아래 폴더를 확인할 필요는 없습니다.
2단계: 파일 구조 검사
먼저 업로드된 파일을 검사하여 스키마를 파악합니다:
python /mnt/skills/public/data-analysis/scripts/analyze.py \
--files /mnt/user-data/uploads/data.xlsx \
--action inspect
다음을 반환합니다:
- 시트 이름 (Excel) 또는 파일 이름 (CSV)
- 컬럼 이름, 데이터 타입, null이 아닌 개수
- 시트/파일별 행 수
- 샘플 데이터 (처음 5행)
3단계: 분석 수행
스키마를 기반으로 사용자의 질문에 답변하는 SQL 쿼리를 구성합니다.
SQL 질의 실행
python /mnt/skills/public/data-analysis/scripts/analyze.py \
--files /mnt/user-data/uploads/data.xlsx \
--action query \
--sql "SELECT category, COUNT(*) as count, AVG(amount) as avg_amount FROM Sheet1 GROUP BY category ORDER BY count DESC"
통계 요약 생성
python /mnt/skills/public/data-analysis/scripts/analyze.py \
--files /mnt/user-data/uploads/data.xlsx \
--action summary \
--table Sheet1
각 숫자형 컬럼에 대해 반환: 개수, 평균, 표준편차, 최소값, 25%, 50%, 75%, 최대값, null 개수. 문자열 컬럼에 대해: 개수, 고유값, 최빈값, 빈도, null 개수.
결과 내보내기
python /mnt/skills/public/data-analysis/scripts/analyze.py \
--files /mnt/user-data/uploads/data.xlsx \
--action query \
--sql "SELECT * FROM Sheet1 WHERE amount > 1000" \
--output-file /mnt/user-data/outputs/filtered-results.csv
지원되는 출력 형식 (확장자로 자동 감지):
.csv— 쉼표로 구분된 값.json— JSON 레코드 배열.md— Markdown 테이블
매개변수
| 매개변수 | 필수 | 설명 |
|---|---|---|
--files | 예 | 공백으로 구분된 Excel/CSV 파일 경로 |
--action | 예 | 다음 중 하나: inspect, query, summary |
--sql | query용 | 실행할 SQL 질의 |
--table | summary용 | 요약할 테이블/시트 이름 |
--output-file | 아니오 | 결과 내보내기 경로 (CSV/JSON/MD) |
[!참고] Python 파일을 읽지 말고 매개변수와 함께 호출만 하세요.
테이블 명명 규칙
- Excel 파일: 각 시트가 시트 이름을 딴 테이블이 됩니다 (예:
Sheet1,Sales,Revenue) - CSV 파일: 테이블 이름은 확장자를 제외한 파일 이름입니다 (예:
data.csv→data) - 여러 파일: 모든 파일의 모든 테이블이 동일한 질의 컨텍스트에서 사용 가능하여 파일 간 조인이 가능합니다.
- 특수 문자: 공백이나 특수 문자가 있는 시트/파일 이름은 자동 정리됩니다 (공백 → 밑줄). 숫자로 시작하거나 특수 문자가 포함된 이름은 큰따옴표를 사용하세요. 예:
"2024_Sales"
분석 패턴
기본 탐색
-- 행 수
SELECT COUNT(*) FROM Sheet1
-- 컬럼의 고유값
SELECT DISTINCT category FROM Sheet1
-- 값 분포
SELECT category, COUNT(*) as cnt FROM Sheet1 GROUP BY category ORDER BY cnt DESC
-- 날짜 범위
SELECT MIN(date_col), MAX(date_col) FROM Sheet1
집계 및 그룹화
-- 카테고리 및 월별 수익
SELECT category, DATE_TRUNC('month', order_date) as month,
SUM(revenue) as total_revenue
FROM Sales
GROUP BY category, month
ORDER BY month, total_revenue DESC
-- 지출 상위 10명 고객
SELECT customer_name, SUM(amount) as total_spend
FROM Orders GROUP BY customer_name
ORDER BY total_spend DESC LIMIT 10
파일 간 조인
-- 다른 파일의 고객 정보와 판매 조인
SELECT s.order_id, s.amount, c.customer_name, c.region
FROM sales s
JOIN customers c ON s.customer_id = c.id
WHERE s.amount > 500
윈도우 함수
-- 누적 합계 및 순위
SELECT order_date, amount,
SUM(amount) OVER (ORDER BY order_date) as running_total,
RANK() OVER (ORDER BY amount DESC) as amount_rank
FROM Sales
피벗 스타일 분석
-- 카테고리별 월별 수익
SELECT category,
SUM(CASE WHEN MONTH(date) = 1 THEN revenue END) as Jan,
SUM(CASE WHEN MONTH(date) = 2 THEN revenue END) as Feb,
SUM(CASE WHEN MONTH(date) = 3 THEN revenue END) as Mar
FROM Sales
GROUP BY category
전체 예제
사용자가 sales_2024.xlsx(시트: Orders, Products, Customers)를 업로드하고 다음과 같이 요청합니다: "판매 데이터를 분석해 주세요. 수익별 상위 제품과 월별 추세를 보여주세요."
1단계: 파일 검사
python /mnt/skills/public/data-analysis/scripts/analyze.py \
--files /mnt/user-data/uploads/sales_2024.xlsx \
--action inspect
2단계: 수익별 상위 제품
python /mnt/skills/public/data-analysis/scripts/analyze.py \
--files /mnt/user-data/uploads/sales_2024.xlsx \
--action query \
--sql "SELECT p.product_name, SUM(o.quantity * o.unit_price) as total_revenue, SUM(o.quantity) as total_units FROM Orders o JOIN Products p ON o.product_id = p.id GROUP BY p.product_name ORDER BY total_revenue DESC LIMIT 10"
3단계: 월별 수익 추세
python /mnt/skills/public/data-analysis/scripts/analyze.py \
--files /mnt/user-data/uploads/sales_2024.xlsx \
--action query \
--sql "SELECT DATE_TRUNC('month', order_date) as month, SUM(quantity * unit_price) as revenue FROM Orders GROUP BY month ORDER BY month" \
--output-file /mnt/user-data/outputs/monthly-trends.csv
4단계: 통계 요약
python /mnt/skills/public/data-analysis/scripts/analyze.py \
--files /mnt/user-data/uploads/sales_2024.xlsx \
--action summary \
--table Orders
발견된 사실, 추세 및 실행 가능한 인사이트에 대한 명확한 설명과 함께 결과를 사용자에게 제시합니다.
다중 파일 예제
사용자가 orders.csv와 customers.xlsx를 업로드하고 다음과 같이 요청합니다: "어느 지역이 가장 높은 평균 주문 금액을 가지고 있나요?"
python /mnt/skills/public/data-analysis/scripts/analyze.py \
--files /mnt/user-data/uploads/orders.csv /mnt/user-data/uploads/customers.xlsx \
--action query \
--sql "SELECT c.region, AVG(o.amount) as avg_order_value, COUNT(*) as order_count FROM orders o JOIN Customers c ON o.customer_id = c.id GROUP BY c.region ORDER BY avg_order_value DESC"
출력 처리
분석 후:
- 질의 결과를 대화에서 포맷된 테이블로 직접 표시
- 큰 결과는 파일로 내보내고
present_files도구로 공유 - 항상 일반 언어로 핵심 요점과 함께 발견된 사실을 설명
- 흥미로운 패턴이 있을 때 후속 분석 제안
- 사용자가 보관하고 싶어하면 결과 내보내기 제안
캐싱
스크립트는 로드된 데이터를 자동으로 캐시하여 매 호출마다 파일을 다시 파싱하지 않습니다:
- 처음 로드 시 파일이 파싱되어
/mnt/user-data/workspace/.data-analysis-cache/아래 영구 DuckDB 데이터베이스에 저장됩니다. - 캐시 키는 모든 입력 파일 내용의 SHA256 해시입니다. 파일이 변경되면 새 캐시가 생성됩니다.
- 동일한 파일에 대한 후속 호출은 캐시된 데이터베이스를 직접 사용합니다 (거의 즉시 시작).
- 캐시는 투명하게 작동하며 추가 매개변수가 필요하지 않습니다.
이는 동일한 데이터 파일에 대해 여러 질의를 실행할 때 특히 유용합니다 (검사 → 질의 → 요약).
참고 사항
- DuckDB는 윈도우 함수, CTE, 서브쿼리 및 고급 집계를 포함한 완전한 SQL을 지원합니다.
- Excel 날짜 컬럼은 자동으로 파싱됩니다. DuckDB 날짜 함수(
DATE_TRUNC,EXTRACT등)를 사용하세요. - 매우 큰 파일(100MB 이상)의 경우 DuckDB가 모든 것을 메모리에 로드하지 않고 효율적으로 처리합니다.
- 공백이 포함된 컬럼 이름은 큰따옴표로 접근할 수 있습니다:
"Column Name"