본문 바로가기
개발기록/python

[python] CSV 파일 합치기 프로그램 만들기 (tkinter GUI)

by spectrum20 2024. 3. 10.

회사에서 일할 때 쓰려고 만든 csv 파일 합치는 매크로 파일

야매로 만들고 ChatGPT 사용해서 교정받았다

(ChatGPT 미첫다...)

 

 

실행방법

 

1. 코드를 실행하면 아래와 같은 GUI 창이 나타난다

 

2. 정렬순서, merge할 행/열, 합칠 방향을 선택 후, Merge 버튼을 누른다

 

 

3. 합칠 csv 파일들을 선택한 뒤, 열기 버튼을 누른다

 

4. 선택한 영역이 합쳐진 엑셀파일이 자동으로 열림

 

 

 

코드
import pandas as pd
import tkinter as tk
from tkinter import filedialog
import os
import re


class CSVFileMerger:
    def __init__(self, root):
        self.root = root
        self.files = []
        self.r = tk.IntVar()
        self.r2 = tk.IntVar()
        self.setup_gui()

    def setup_gui(self):
        self.root.geometry('300x300')
        self.root.resizable(False, False)

        self.radio1 = tk.Radiobutton(self.root, text="시간순", variable=self.r, value=1)
        self.radio1.select()
        self.radio2 = tk.Radiobutton(self.root, text='파일명순', variable=self.r, value=2)
        self.radio3 = tk.Radiobutton(self.root, text='시간역순', variable=self.r, value=3)
        self.radio4 = tk.Radiobutton(self.root, text='파일명역순', variable=self.r, value=4)

        self.row_label = tk.Label(self.root, text="행 시작 : ")
        self.row_entry = tk.Entry(self.root, width=5)

        self.row_label2 = tk.Label(self.root, text="행 끝 : ")
        self.row_entry2 = tk.Entry(self.root, width=5)

        self.col_label = tk.Label(self.root, text="열 시작 : ")
        self.col_entry = tk.Entry(self.root, width=5)

        self.col_label2 = tk.Label(self.root, text="열 시작 : ")
        self.col_entry2 = tk.Entry(self.root, width=5)

        self.radio5 = tk.Radiobutton(self.root, text="가로", variable=self.r2, value=1)
        self.radio5.select()
        self.radio6 = tk.Radiobutton(self.root, text='세로', variable=self.r2, value=2)

        self.select_button = tk.Button(self.root, text='Merge', command=self.select_data)

        # Grid Placement
        self.radio1.grid(row=0, column=0)
        self.radio2.grid(row=0, column=1)
        self.radio3.grid(row=1, column=0)
        self.radio4.grid(row=1, column=1)

        self.row_label.grid(row=2, column=0)
        self.row_entry.grid(row=2, column=1)
        self.row_label2.grid(row=2, column=2)
        self.row_entry2.grid(row=2, column=3)

        self.col_label.grid(row=3, column=0)
        self.col_entry.grid(row=3, column=1)
        self.col_label2.grid(row=3, column=2)
        self.col_entry2.grid(row=3, column=3)

        self.radio5.grid(row=4, column=0)
        self.radio6.grid(row=4, column=1)

        self.select_button.grid(row=5, column=2)

    def sort_filenames(self, filenames):
        def extract_number(filename):
            return int(re.findall('\d+', filename)[0])
        return sorted(filenames, key=extract_number)

    def select_data(self):
        sort = self.r.get()
        direction = self.r2.get()
        row_start = int(self.row_entry.get()) - 1
        col_start = int(self.col_entry.get()) - 1
        row_end = int(self.row_entry2.get())
        col_end = int(self.col_entry2.get())

        self.files = filedialog.askopenfilenames(title="Select CSV files to merge")
        self.files = list(self.files)

        sorted_files = self.files

        if sort == 1:
            sorted_files.sort(key=os.path.getmtime)
        elif sort == 2:
            sorted_files = self.sort_filenames(sorted_files)
        elif sort == 3:
            sorted_files.sort(key=os.path.getmtime)
            sorted_files = sorted_files[::-1]
        else:
            sorted_files = self.sort_filenames(sorted_files)
            sorted_files = sorted_files[::-1]

        merged_data = pd.DataFrame()

        for file in sorted_files:
            data = pd.read_csv(file, header=None)
            data = data.iloc[row_start:row_end, col_start:col_end]

            if direction == 2:
                merged_data = pd.concat([merged_data, data])
            else:
                merged_data = pd.concat([merged_data, data], axis=1)

        file_path = os.path.join(os.path.dirname(self.files[0]), 'merged_data.csv')
        merged_data.to_csv(file_path, index=False)

        os.startfile(file_path)


if __name__ == "__main__":
    root = tk.Tk()
    app = CSVFileMerger(root)
    root.mainloop()

 

 


+ 위 코드로 csv 파일 합치기를 진행하면, csv 파일 양식에 따라 Tokenizing 에러가 발생할 수 있다

 

pandas.errors.ParserError: Error tokenizing data

 

csv파일이 행과 열이 일정하지 않아서 발생하는 오류인 듯

 

해결방법은 csv파일을 csv리더로 한줄씩 읽어서 리스트에 추가한 뒤, 데이터프레임 형태로 만들면 된다.

import csv

for file in sorted_file:
	f = open(file)
    reader = csv.reader(f)
    csv_list = []
    for i in reader:
    	csv_list.append(i)
    f.close()
    
    data = pd.DataFrame(csv_list[row_start:row_end])
    data = data.iloc[:, col_start:col_end]

 

 

 

반응형

댓글