반응형
반응형

[python]  Faker 라이브러리로 Dummy 데이터 만들기

 

pip install Faker
    
    1.faker는 이름, 주소, 이메일, 전화번호 등 다양한 종류의 가짜 데이터를 만들어주는 파이썬 패키지입니다. 
       Faker 객체를 생성하고, 해당 객체가 제공하는 다양한 메소드를 호출해 원하는 형식의 데이터를 얻을 수 있어요.
    2.Faker는 국가별 언어 설정을 지원해요. 예를 들어, Faker('ko_KR')를 사용하면 한국어 이름, 주소, 주민등록번호 등 

       한국 특화된 데이터를 생성할 수 있습니다.

 

 

""" pip install Faker 

"""

from faker import Faker

# Faker 객체 생성
fake = Faker('ko_KR') # 'ko_KR'은 한국어 더미 데이터를 생성하도록 설정합니다.

# 기본 정보 더미 데이터 생성
print("--- 기본 정보 ---")
print("이름:", fake.name())
print("주소:", fake.address())
print("전화번호:", fake.phone_number())
print("이메일:", fake.email())
print("회사:", fake.company())
print("직업:", fake.job())
print("생일:", fake.date_of_birth())
print("-" * 20)

# 텍스트 및 문장 더미 데이터
print("--- 텍스트 ---")
print("문장:", fake.sentence())
print("단락:", fake.paragraph())
print("텍스트:", fake.text())
print("-" * 20)

# 숫자 및 날짜/시간 더미 데이터
print("--- 숫자/시간 ---")
print("정수:", fake.random_int(min=1, max=100))
print("날짜:", fake.date_this_year())
print("시간:", fake.time())
print("-" * 20)

# 금융 정보 더미 데이터
print("--- 금융 정보 ---")
print("신용카드 번호:", fake.credit_card_number())
print("통화 코드:", fake.currency_code())
print("-" * 20)

# 한국어(ko_KR)에서만 제공하는 특별한 더미 데이터
print("--- 한국어 특화 ---")
print("주민등록번호:", fake.ssn())
print("우편번호:", fake.postcode())
print("-" * 20)

# 여러 개의 데이터 생성
print("--- 사용자 목록 ---")
for _ in range(3):
    print({
        '이름': fake.name(),
        '이메일': fake.email(),
        '주소': fake.address(),
        '나이': fake.random_int(min=20, max=60),
    })
print("-" * 20)
반응형
반응형

voronoi diagram for generative geometry using python

 

파이썬을 사용하여 제너레이티브 지오메트리(generative geometry)를 위한 보로노이 다이어그램(Voronoi diagram)을 생성하는 것은 널리 사용되는 강력한 기법입니다.

 

이 과정은 일련의 무작위 점을 생성한 다음, SciPy와 같은 라이브러리를 사용하여 이 점들에 대한 근접성에 따라 평면을 분할하는 보로노이 다이어그램을 계산하는 것을 포함합니다.

 

이렇게 분할된 공간은 복잡하고 유기적으로 보이는 디자인을 만드는 데 사용될 수 있습니다.

 

 

"""
파이썬을 사용하여 제너레이티브 지오메트리(generative geometry)를 위한 
 보로노이 다이어그램(Voronoi diagram)을 생성하는 것은 널리 사용되는 강력한 기법입니다. 
이 과정은 일련의 무작위 점을 생성한 다음, SciPy와 같은 라이브러리를 사용하여 
 이 점들에 대한 근접성에 따라 평면을 분할하는 보로노이 다이어그램을 계산하는 것을 포함합니다.
이렇게 분할된 공간은 복잡하고 유기적으로 보이는 디자인을 만드는 데 사용될 수 있습니다.
"""

import numpy as np
from scipy.spatial import Voronoi, voronoi_plot_2d
import matplotlib.pyplot as plt

# 1. Generate 20 random 2D points
points = np.random.rand(20, 2)

# 2. Compute the Voronoi diagram
vor = Voronoi(points)

# 3. Plot the diagram
fig = voronoi_plot_2d(vor)
plt.show()

핵심 라이브러리

파이썬에서 보로노이 다이어그램을 생성하고 시각화하려면 주로 다음 라이브러리가 필요합니다:

  • NumPy: 수치 연산을 위해, 특히 점들의 좌표를 생성하고 다루는 데 사용됩니다.
  • SciPy: 핵심 보로노이 다이어그램 계산을 위해. scipy.spatial.Voronoi 클래스가 주요 도구입니다.
  • Matplotlib: 결과 다이어그램을 플롯하고 시각화하는 데 사용됩니다.

기본 보로노이 다이어그램 생성 단계

다음 코드는 이 라이브러리들을 사용한 간단한 예시를 보여줍니다.

  1. 무작위 점 생성: 보로노이 셀의 "씨앗(seeds)" 또는 "생성자(generators)" 역할을 할 일련의 무작위 2D 점을 만듭니다.
  2. 보로노이 다이어그램 계산: 점 집합을 scipy.spatial.Voronoi에 전달합니다. 이 객체는 보로노이 셀의 꼭짓점과 그 관계를 포함하여 다이어그램에 대한 모든 필수 정보를 담고 있습니다.
  3. 다이어그램 플롯: scipy.spatial.voronoi_plot_2d를 사용하여 결과를 시각화합니다. 이 함수는 보로노이 객체를 받아 다이어그램의 선과 꼭짓점을 플롯하며, 종종 원래의 점들이 함께 겹쳐서 표시됩니다.

 

반응형
반응형

[python] 과거 당첨번호 중 출현빈도 상위 기준으로 로또번호 추출

 

 

 


"""
    python 기존 로또 당첨번호를 이용한 로또 번호 추출 프로그램

"""



import pandas as pd
import random
from collections import Counter

def load_winning_numbers(filepath="winning_numbers.csv"):
    """
    CSV 파일에서 로또 당첨 번호를 불러옵니다.
    """
    try:
        df = pd.read_csv(filepath)
        # 추첨 번호(drwtNo1 ~ drwtNo6)만 추출합니다.
        winning_nums_cols = [f'drwtNo{i}' for i in range(1, 7)]
        return df[winning_nums_cols]
    except FileNotFoundError:
        print(f"오류: '{filepath}' 파일을 찾을 수 없습니다.")
        print("동행복권 웹사이트 등에서 당첨 번호 데이터를 CSV 파일로 다운로드하여 같은 폴더에 넣어주세요.")
        return None
    except Exception as e:
        print(f"데이터 로딩 중 오류 발생: {e}")
        return None

def analyze_number_frequency(winning_numbers_df):
    """
    각 숫자의 출현 빈도를 분석합니다.
    """
    all_numbers = []
    # 모든 당첨 번호 목록을 하나로 합칩니다.
    for index, row in winning_numbers_df.iterrows():
        all_numbers.extend(row.tolist())
    
    # 각 숫자의 출현 횟수를 셉니다.
    number_counts = Counter(all_numbers)
    
    # 빈도수 기준으로 내림차순 정렬
    sorted_counts = sorted(number_counts.items(), key=lambda item: item[1], reverse=True)
    
    return dict(sorted_counts) # {숫자: 빈도수} 형태로 반환

def generate_random_numbers():
    """
    가장 기본적인 방법으로 6개의 무작위 로또 번호를 생성합니다.
    """
    return sorted(random.sample(range(1, 46), 6))


def generate_numbers_based_on_frequency(number_frequency, num_recommendations=1, exclude_numbers=None):
    """
    과거 당첨 빈도를 기반으로 로또 번호를 추천합니다.
    (이 전략은 통계적 예측이 아닌, 자주 나온 번호 중에서 무작위로 선택하는 방식입니다.)
    """
    if number_frequency is None:
        print("경고: 번호 빈도 분석 데이터를 찾을 수 없어 무작위 번호를 생성합니다.")
        return [generate_random_numbers() for _ in range(num_recommendations)]

    # 빈도수가 높은 순서대로 숫자 목록을 만듭니다.
    # (실제로는 빈도수에 가중치를 두어 추출하는 더 복잡한 알고리즘도 가능합니다)
    sorted_numbers = list(number_frequency.keys())
    
    recommendations = []
    for _ in range(num_recommendations):
        generated_numbers = set()
        
        # 이미 추천된 번호들을 제외할 경우
        if exclude_numbers:
            available_numbers = [num for num in sorted_numbers if num not in exclude_numbers]
        else:
            available_numbers = sorted_numbers
        
        # 혹시 available_numbers가 6개 미만일 경우를 대비
        if len(available_numbers) < 6:
            print("경고: 추천할 수 있는 숫자가 충분하지 않습니다. 모든 번호에서 추출합니다.")
            available_numbers = list(range(1, 46))

        # 빈도수 기반으로 6개의 고유한 번호 추출
        # (단순히 빈도수 높은 순서대로 앞에서 6개 뽑는 것이 아니라,
        # 빈도수를 가중치로 해서 랜덤 샘플링하는 것이 더 무작위적입니다.)
        # 여기서는 편의상, 빈도수 높은 순서대로 나열된 리스트에서 랜덤하게 뽑습니다.
        
        # 더 나은 방법: 빈도수에 비례하여 숫자를 뽑기 (예: [1,1,1,2,2,3] -> 1,2,3이 나올 확률이 다름)
        # 이 예시에서는 단순화하여, 빈도수 순서대로 나열된 숫자 리스트에서 6개를 고유하게 뽑습니다.
        
        # 자주 나온 번호들 중에서 (예: 상위 20개) 무작위로 6개 선택
        top_n_numbers = sorted_numbers[:20] # 상위 20개 번호
        if len(top_n_numbers) < 6:
             # 혹시 상위 20개보다 전체 숫자가 적다면
             top_n_numbers = sorted_numbers

        # 상위 번호들 또는 전체 번호에서 무작위로 6개 선택
        try:
            chosen_numbers = sorted(random.sample(top_n_numbers, 6))
        except ValueError: # 만약 top_n_numbers가 6개 미만일 경우
            chosen_numbers = sorted(random.sample(available_numbers, 6))

        recommendations.append(chosen_numbers)
        
    return recommendations

# --- 메인 프로그램 ---
if __name__ == "__main__":
    file_path = "winning_numbers.csv" # 로또 당첨 번호 CSV 파일 경로
    
    print("==== 로또 번호 추천 프로그램 ====")
    
    # 1. 과거 당첨 번호 로드
    winning_numbers_df = load_winning_numbers(file_path)
    
    if winning_numbers_df is not None:
        # 2. 번호 빈도 분석
        number_frequency = analyze_number_frequency(winning_numbers_df)
        print("\n[과거 당첨 번호 출현 빈도 (상위 10개)]")
        for number, count in list(number_frequency.items())[:10]:
            print(f"  - 숫자 {number}: {count}회")

        # 3. 로또 번호 추천
        num_sets_to_recommend = 5 # 몇 세트의 번호를 추천받을지 설정
        
        # 빈도 기반 추천
        frequency_based_recommendations = generate_numbers_based_on_frequency(
            number_frequency, 
            num_recommendations=num_sets_to_recommend
        )
        
        print(f"\n[과거 당첨 빈도 기반 추천 번호 ({num_sets_to_recommend} 세트)]")
        for i, numbers in enumerate(frequency_based_recommendations):
            print(f"  세트 {i+1}: {numbers}")
            
        # 단순 무작위 추천 (비교용)
        random_recommendations = [generate_random_numbers() for _ in range(num_sets_to_recommend)]
        print(f"\n[단순 무작위 추천 번호 ({num_sets_to_recommend} 세트)]")
        for i, numbers in enumerate(random_recommendations):
            print(f"  세트 {i+1}: {numbers}")
            
    else:
        print("\n데이터 로딩 실패로 인해 번호 추천을 진행할 수 없습니다.")
        print("프로그램을 종료합니다.")
반응형
반응형

[python] Blackhole Glow using python

 

import matplotlib.pyplot as plt, numpy as np
plt.style.use("dark_background")
O = np.linspace(0, 10*np.pi, 2000)
r = 1/(1+0.2*O)
x, y = r*np.cos(O), r*np.sin(O)
plt.scatter(x, y, c=O, cmap="magma", s=3)
plt.axis("equal");
plt.show()

 

반응형
반응형

 

 ./input/ 폴더 안에 있는 엑셀파일을 찾아서 데이터 있는 셀의 앞뒤 공백을 삭제

 

# pip install pandas openpyxl


"""
    ./input/ 폴더 안에 있는 엑셀파일을 찾아서 데이터 있는 셀의 앞뒤 공백을 삭제

"""

import pandas as pd
import os

# 엑셀 파일이 있는 폴더 경로
input_folder = "./input/"

# 공백이 제거된 파일을 저장할 폴더 (원본 폴더에 저장)
output_folder = "./output/"

# 출력 폴더가 없으면 생성
if not os.path.isdir(output_folder):
    os.makedirs(output_folder)

# input 폴더 내의 모든 파일 목록 가져오기
files = os.listdir(input_folder)

print(f"'{input_folder}' 폴더에서 엑셀 파일을 찾고 있습니다...")

# 파일 목록을 순회
for filename in files:
    # 파일 확장자가 .xlsx 또는 .xls인지 확인
    if filename.endswith(".xlsx") or filename.endswith(".xls"):
        print(f"\n파일 '{filename}' 처리 중...")
        
        # 전체 파일 경로 설정
        file_path = os.path.join(input_folder, filename)
        
        try:
            # 엑셀 파일을 데이터프레임으로 읽어오기
            # 모든 시트를 읽어오기 위해 sheet_name=None 옵션 사용
            #excel_data = pd.read_excel(file_path, sheet_name=None) # 헤더 제외
            excel_data = pd.read_excel(file_path, sheet_name=None, header=0, dtype=str) # 모든 데이터를 문자열로 읽기
            
            # 수정한 내용을 저장할 새로운 엑셀 파일 객체 생성
            output_filepath = os.path.join(output_folder, f"{os.path.splitext(filename)[0]}_cleaned{os.path.splitext(filename)[1]}")
            
            with pd.ExcelWriter(output_filepath, engine='openpyxl') as writer:
                # 각 시트(Sheet)를 순회하며 작업
                for sheet_name, df in excel_data.items():
                    print(f"  - 시트 '{sheet_name}' 공백 삭제 중...")
                    
                    # 문자열 타입의 열만 선택하여 공백 제거
                    for col in df.columns:
                        if df[col].dtype == 'object':
                            # .str.strip() 메서드로 앞뒤 공백 제거
                            #df[col] = df[col].astype(str).str.strip()                            
                            df[col] = df[col].fillna('').astype(str).str.strip() # NaN 값이 있을 때 오류 방지
                            print(df[col])
                    
                    # 수정된 데이터프레임을 새로운 엑셀 파일의 해당 시트에 저장
                    df.to_excel(writer, sheet_name=sheet_name, index=False)
            
            print(f"'{filename}' 파일 처리가 완료되었습니다. '{output_filepath}'에 저장됨.")

        except Exception as e:
            print(f"  - 오류 발생: '{filename}' 파일을 처리할 수 없습니다. 오류: {e}")

print("\n모든 엑셀 파일 처리가 완료되었습니다.")
반응형
반응형

[python] python, rust 의 관계

 

파이썬(Python)과 러스트(Rust)는 서로 경쟁 관계라기보다는 상호 보완적인 관계에 가깝습니다. 두 언어는 설계 철학부터 특징까지 매우 다르며, 각각의 강점을 활용해 시너지를 낼 수 있습니다.

 

 

두 언어의 근본적인 차이점

특징 파이썬(Python) 러스트(Rust)
언어 레벨 고수준 언어 (High-level) 저수준 언어 (Low-level)
컴파일 방식 인터프리터 방식 (실행 시 해석) 컴파일 방식 (실행 전 기계어로 변환)
타입 시스템 동적 타입 (Dynamic) 정적 타입 (Static)
메모리 관리 자동 (가비지 컬렉터) 수동 (소유권 시스템)
주요 강점 생산성, 쉬운 문법, 방대한 라이브러리 성능, 안정성, 메모리 안전성
주요 단점 느린 속도, 높은 메모리 사용량 어려운 학습 곡선, 긴 개발 시간

 

상호 보완적인 관계: 왜 함께 사용하는가?

파이썬은 개발 속도가 빠르고 배우기 쉬워 전체 애플리케이션의 뼈대를 만드는 데 탁월합니다. 하지만 속도가 중요하거나 복잡한 계산을 처리해야 하는 작업에서는 성능의 한계가 명확합니다.

바로 이 지점에서 러스트가 파이썬의 단점을 완벽하게 보완해 줍니다. 러스트는 뛰어난 성능과 메모리 효율성을 자랑하므로, 파이썬으로 만든 애플리케이션의 '병목 현상(bottleneck)'을 해결하는 데 이상적입니다.

예시: 파이썬으로 웹 서버를 구축했다고 가정해 봅시다. 웹 서버의 전체적인 로직은 파이썬으로 빠르게 개발할 수 있습니다. 그러나 특정 요청을 처리하는 과정에서 데이터 분석이나 복잡한 이미지 처리와 같은 고성능 작업이 필요할 수 있습니다.

이 경우, 해당 고성능 작업 부분만을 러스트로 작성합니다. 러스트는 이 작업을 매우 빠르게 처리하고, 그 결과를 다시 파이썬으로 전달해 줍니다. 이렇게 하면 파이썬의 빠른 개발 생산성러스트의 탁월한 실행 속도를 모두 얻을 수 있습니다.

실제 협업 방식

러스트로 작성된 코드는 '파이썬 모듈' 형태로 컴파일될 수 있습니다. **PyO3**나 **rust-cpython**과 같은 라이브러리를 사용하면, 러스트의 함수나 클래스를 마치 파이썬 함수처럼 호출할 수 있는 모듈을 쉽게 만들 수 있습니다.

즉, 러스트는 파이썬의 '성능을 위한 보조 도구' 역할을 하며, 파이썬 생태계에 새로운 가능성을 불어넣고 있습니다.

 

 

 

러스트 재단에서 개발되고 있는 메모리 안전성과 성능 및 편의성에 중점을 둔 프로그래밍 언어이다. 가비지 컬렉터 없이 메모리 안전성을 제공하는 대표적인 언어다. C++의 대체재로서 등장했다.

https://youtu.be/5C_HPTJg5ek

 

반응형

+ Recent posts