Projects/Texcel

[Python]여러개의 텍스트 파일을 열 단위로 엑셀 파일로 옮기기

Kellang 2022. 11. 3. 22:04

https://github.com/kelly-chui/texcel-py

 

GitHub - kelly-chui/texcel-py: Digital Amplifier의 hit rate 결과로 출력된 text 파일을 Excel로 옮겨주는 프로그

Digital Amplifier의 hit rate 결과로 출력된 text 파일을 Excel로 옮겨주는 프로그램 - kelly-chui/texcel-py

github.com

 

학부연구원을 하고 있는 친구에게 연락이 왔다. Digital Amplifier를 설계했고, 한번 시뮬레이션을 돌리면 약 40개 정도의 Text 파일이 생성되는데 이걸 엑셀에 하나하나 붙여넣기가 너무 귀찮다고 한다. 

 

Python도 복습할 겸 친구도 도와주기 위해 코드를 작성해보자.

Python에서 Excel 파일을 다룰려면 가장 쉬운 방법이 pandas를 쓰는 것이다.

파일명이 위 사진과 같이 되어있어서, 파일명 정렬을 해줘야 했다. natsort같은 외부 라이브러리를 쓸까 하다가 그냥 직접 작성했다:

def _structured_key(self, filename):
    parts = filename.split('_')
    key = []
    for part in parts:
        if part.isdigit():
            key.append(int(part))
        else:
            nums = re.findall(r'\d+', part)
            key.extend(int(n) for n in nums)
    return key

 

특별한 부분은 없지만, text 파일 내부의 데이터가 위와 같이 생겼으므로 전처리가 필요하다. 중간에 실패하는 경우도 있는 것 같더라. 

def _extract_number(self, value):
    if isinstance(value, str) and "=" in value:
        try:
            return float(value.split('=')[1])
        except ValueError:
            return "failed"
    return "failed"
def make_excel_file(self):
    if not self.load_path or not self.save_path:
        messagebox.showwarning("Notice", "No valid directory has been selected. Please reselect")
        return

    txt_files = sorted(
        [f for f in os.listdir(self.load_path) if f.endswith(".txt")],
        key=self._structured_key
    )

    df_list = []
    for file in txt_files:
        with open(os.path.join(self.load_path, file), 'r') as txt_file:
            df = pd.read_csv(txt_file, header=None, names=None)
            df_list.append(df)

    if not df_list:
        messagebox.showwarning("Notice", "No .txt files found in the load path.")
        return

    result_df = pd.concat(df_list, axis=1)
    result_df = result_df.map(self._extract_number)

    now = datetime.now().strftime("%m_%d_%Y_%H_%M_%S")
    filename = f"result_{now}.xlsx"
    result_path = os.path.join(self.save_path, filename)

    with pd.ExcelWriter(result_path, engine="openpyxl") as writer:
        result_df.to_excel(writer, index=False, header=False)

    messagebox.showinfo("Complete", f"Saved to {result_path}")