수요기관별 세부 품목 구매 내역 및 패턴 분석 보고서 코드
민광석
2024-11-11 15:29
327
0
0
본문
import pandas as pd
from sqlalchemy import create_engine
from fpdf import FPDF
from datetime import datetime
# MySQL 데이터베이스 연결 설정 (SQLAlchemy 사용)
def connect_to_db():
engine = create_engine('mysql+mysqlconnector://:@localhost/g2bsaledb')
return engine
# 데이터 가져오기 (다수공급자계약여부가 'Y'인 데이터만 필터링)
def fetch_data():
engine = connect_to_db()
query = """
SELECT 수요기관명, 세부물품분류번호, 납품요구접수일자, 수량, 세부품명, 단위, 다수공급자계약여부
FROM g2b_data
WHERE 다수공급자계약여부 = 'Y'
AND 납품요구접수일자 BETWEEN '20050101' AND '20231231';
"""
df = pd.read_sql(query, engine)
return df
# 데이터 전처리 (날짜 형식 변환)
def preprocess_data(df):
df['납품요구접수일자'] = pd.to_datetime(df['납품요구접수일자'], format='%Y%m%d')
df['연도'] = df['납품요구접수일자'].dt.year
return df
# 수요기관별로 구매 내역 및 패턴 분석 정리
def generate_purchase_summary(df):
summary = {}
grouped = df.groupby(['수요기관명', '세부품명', '연도', '단위'])['수량'].sum().reset_index()
for institution, group in grouped.groupby('수요기관명'):
summary[institution] = {}
for item, item_group in group.groupby('세부품명'):
unit = item_group['단위'].iloc[0]
purchase_list = item_group[['연도', '수량']].values.tolist()
annual_mean = item_group['수량'].mean()
large_purchases = item_group[item_group['수량'] > annual_mean * 1.5]
cycle_years = large_purchases['연도'].diff().dropna().mean()
if pd.isna(cycle_years):
cycle_years = None
if not large_purchases.empty:
last_large_purchase = large_purchases['연도'].max()
next_large_purchase = int(last_large_purchase + cycle_years) if cycle_years else "예측 불가"
else:
next_large_purchase = "예측 불가"
purchase_details = [f"{year}년 {quantity}{unit}" for year, quantity in purchase_list]
pattern_analysis = f"연간 평균 {annual_mean:.0f}{unit} 구매"
if not large_purchases.empty and cycle_years:
pattern_analysis += f", {int(cycle_years)}년 간격으로 평균 {int(large_purchases['수량'].mean()):.0f}{unit}의 대량 구매 (최근 대량 구매 {last_large_purchase}년, {next_large_purchase}년 예상)"
summary[institution][item] = {
"details": purchase_details,
"pattern": pattern_analysis
}
return summary
# PDF 보고서 생성 (한글 폰트 추가)
class PDFReport(FPDF):
def header(self):
self.add_font('NanumGothic', '', 'NanumGothic.ttf', uni=True)
self.set_font('NanumGothic', '', 14)
self.cell(0, 10, '수요기관별 세부 품목 구매 내역 및 패턴 분석 보고서', ln=True, align='C')
self.ln(10)
def add_institution_summary(self, summary):
self.set_font('NanumGothic', '', 12)
for institution, items in summary.items():
self.cell(0, 10, f'{institution} 구매 내역', ln=True)
for idx, (item, data) in enumerate(items.items(), start=1):
details_str = ', '.join(data['details'])
self.multi_cell(0, 10, f"{idx}. {item} : {details_str}")
self.set_font('NanumGothic', 'I', 11)
self.multi_cell(0, 10, f"- 구매 패턴 분석 -\n{idx}. {item} : {data['pattern']}")
self.set_font('NanumGothic', '', 12)
self.ln(10)
def generate_pdf_report(summary):
pdf = PDFReport()
pdf.add_page()
pdf.add_institution_summary(summary)
pdf.output('institution_purchase_pattern_report.pdf')
print("PDF 보고서가 생성되었습니다: institution_purchase_pattern_report.pdf")
# 메인 실행 함수
def main():
data = fetch_data()
data = preprocess_data(data)
summary = generate_purchase_summary(data)
generate_pdf_report(summary)
if __name__ == "__main__":
main()
0
로그인 후 추천 또는 비추천하실 수 있습니다.
민광석
회원등급 : 최고관리자
포인트 1,800
경험치 233
[레벨 2] - 진행률
9%
가입일
2024-10-21 11:52:45
댓글목록0