質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

223閲覧

Pythonのコードを用いてExcelをtsvに変換する際に日付列の9999/12/31がYYYY/MM/DDではなくYYYY-MM-DD hh:mm:ssのタイムスタンプ型で変換されてしまう

wkbeginner

総合スコア1

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2024/04/04 00:57

実現したいこと

Excelを読み込んでtsvファイルに変換するコードを作成しています。
Excelの各セルの内容は編集せずにそのままtsvファイルに変換する処理を行いたいです。
どなたかご教授いただければ幸いです。

発生している問題・分からないこと

変換元のExcelの列の日付の項目に9999/12/31のような日付が入っていると、YYYY-MM-DD hh:mm:ssのタイムスタンプ形式で変換されてしまいます。通常の2001/01/01のような日付のみの列はYYYY/MM/DDで変換されています。
変換前(Excel)

ID開始日終了日
A2023/01/019999/12/31
A2023/01/012014/02/02

変換後(タブ区切り形式のファイル)

ID開始日終了日
A2023/01/019999-12-31 00:00:00
A2023/01/012014-02-02 00:00:00

デバッグで確認したところ、9999/12/31の列はタイムスタンプ型で読み込んでいるところまで確認できました。

該当のソースコード

Python

1import os 2from tkinter import Tk, filedialog, messagebox 3import pandas as pd 4import csv 5 6 7def select_folder(): 8 root = Tk() 9 root.withdraw() # メインウィンドウを表示しないようにする 10 folder_path = filedialog.askdirectory(title="フォルダを選択してください") 11 12 if folder_path: 13 convert_excel_to_tsv(folder_path) 14 15 16def convert_excel_to_tsv(folder_path): 17 try: 18 files = os.listdir(folder_path) 19 20 for file in files: 21 if file.endswith(".xlsx"): 22 excel_path = os.path.join(folder_path, file) 23 tsv_name = os.path.splitext(file)[0] + ".tsv" 24 tsv_path = os.path.join(folder_path, tsv_name) 25 26 # ExcelファイルをDataFrameとして読み込む 27 df = pd.read_excel(excel_path,engine="openpyxl") 28 29 # DataFrameをタブ区切りのTSVファイルとして保存する 30 df.to_csv(tsv_path, sep='\t', index=False, encoding='utf-8', quoting=csv.QUOTE_NONE) 31 32 #print(f'Converted Excel to TSV: {file} -> {tsv_name}') 33 34 messagebox.showinfo('メッセージ', '処理が完了しました。ExcelファイルをTSVファイルに変換しました。') 35 36 except Exception as e: 37 print(str(e)) 38 messagebox.showinfo(f'エラーが発生しました: {str(e)}') 39 40 41if __name__ == "__main__": 42 select_folder() 43

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果
  • pythonではUNIXの時間の扱いで2038年までしか日時を扱えないという事象までは確認しました。

対応策まで勘案できていない状態です

  • read_excelのdtypeをstrで行う方式も試しましたが、日付の列がすべてタイムスタンプ型になってしまい、断念しました

補足

Python 3.11
pandas 2.2.1
openpyxl 3.1.2
numpy 1.26.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bsdfan

2024/04/05 01:01

タイムスタンプ型とは具体的に何をさしていますか?私の環境では dtype が object で、各要素は datetime.datetime型で入っていました。 型が違っていたらできないかもしれませんが、tsv に出力することができればOKということなら、終了日列を文字列に変換してから出力するのはどうでしょうか。 df['終了日'] = df['終了日'].map(lambda x: x.strftime('%Y/%m/%d'))
wkbeginner

2024/04/05 02:58

can110さん 情報のご提供ありがとうございます。 pandas(openpyxl)ではYYYY-MM-DD hh:mm:ssの形式で解釈しまうのですね。
wkbeginner

2024/04/05 03:06

bsdfanさん コメントありがとうございます。 YYYY-MM-DD hh:mm:ssの形式をタイムスタンプ型と呼んでいました。Pythonの型と混同させてしまうようでしたね。すみません。 御教授いただいたdf['終了日'] = df['終了日'].map(lambda x: x.strftime('%Y/%m/%d'))の記述で9999/12/31のような日付もYYYY/MM/DD形式になっていることを確認できました。ありがとうございました。
guest

回答1

0

ベストアンサー

「9999/12/31」が pandas.Timestamp.max を超えているため pandas.Timestamp 型ではなく datetime.datetime 型(上限は datetime.MAXYEARdatetime.max)で読み込まれていると思われます。

思いついた対応案としては以下になります。

  • 「9999/12/31」の変更が可能なら,上限内の「2261/12/31」等に変更する。

  • 所望の形式(YYYY/MM/DD)の TSV ファイルを作成することが主たる目的なら,エクセルファイルから所望の形式の「文字列」として読み込む。文字列で読み込んでも datetime.date 型等に後から変換することは可能です。

2番目について pandas.read_excel()converters パラメータを用いた記述例を下記に示します。なお,環境は「Python 3.12.2, pandas 2.2.1」です。

Python

1import pandas as pd 2import csv 3 4cvt = lambda x: x.strftime('%Y/%m/%d') 5df = pd.read_excel('example.xlsx', engine="openpyxl", 6 converters={'開始日': cvt, '終了日': cvt}) 7 8df.to_csv('example.tsv', sep='\t', index=False, 9 encoding='utf-8', quoting=csv.QUOTE_NONE) 10 11with open('example.tsv', encoding='utf-8') as f: 12 print(f.read()) 13# ID 開始日 終了日 14# A 2023/01/01 9999/12/31 15# A 2023/01/01 2014/02/02

投稿2024/04/05 14:40

編集2024/04/09 23:51
little_street

総合スコア319

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wkbeginner

2024/04/08 05:18

回答ありがとうございます。 試したところ問題が解決しました! ベストアンサーに選ばせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問