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

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

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

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

解決済

PDF→CSVへ変更したデータの複数ページ出力ができない(to_csv)

syoh0335
syoh0335

総合スコア2

Python

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

1回答

1グッド

1クリップ

239閲覧

投稿2022/11/12 03:26

前提

tabulaを使ってPDFファイルをcsvに変更して、管理しやすくしたいのですが
現在”df.to_csv”でcsvファイルにする際、PDF3枚分の内、1枚(何故か3ページ目)だけしか出力されません。

”df.to_csv”の前のprint(df)では3枚分結果が返ってくるので、printの位置でデータの整形をしないといけないのは、なんとなく分かるのですが、
ネットなどで調べても分からず、打開策が浮かびません。
どこがおかしいのか、問題解決にご助力して頂けると幸いです。
宜しくお願い致します。

実現したいこと

tabulaでPDFから複数ページ抽出したデータを
そのページ数分CSVファイルに出力したいです

発生している問題・エラーメッセージ

最後のページだけCSVファイルに出力される

Python

1ソースコード 2 3 4import pandas as pd 5 6import tabula 7 8 9###PDFファイルパス 10path = 'data/〇〇〇.pdf' 11 12###PDFの読み込み 13dfs = tabula.read_pdf(path, pages='all', lattice=True) 14 15###読み込んだPDFを確認 16# print(dfs) 17 18 19# ###CSVへ出力 20for df in dfs: 21 22 # カラム 23 df.columns = ['取引日付', '取引内容', '出金', '入金', '残高'] 24 25 26 #数値のカンマを消す 27 df['出金'] = df['出金'].replace(',', '', regex=True) 28 df['出金'] = df['出金'].replace(' ', '', regex=True) 29 df['入金'] = df['入金'].replace(',', '', regex=True) 30 df['入金'] = df['入金'].replace(' ', '', regex=True) 31 df['残高'] = df['残高'].replace(',', '', regex=True) 32 df['残高'] = df['残高'].replace(' ', '', regex=True) 33 34 print(df) 35 36 37df.to_csv("result.csv", index=None) 38

補足情報(FW/ツールのバージョンなど)

Python3.9
Pycharm 2022.2.3
pandas 1.5.1
tabula 1.0.5

melian😍を押しています

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

melian

2022/11/12 03:55 編集

df.to_csv("result.csv", index=None) を for ループの内部に入れて、CSVファイルの名前を適宜変更する必要があります。
syoh0335

2022/11/12 04:17

melian様 前回に引き続きコメントありがとうございます。 forループ内に"df.to_csv("result.csv", index=None)"を入れ、CSVファイルの名前を変えたコードを3行追加したら、3ページ共出力することができました。 今まで1行のみしか書いていなかったので、上書きされていたということなのでしょうか? この場合、今は数ページなので適宜変更することは手間ではないですが、もし何百ページ分などを出力したい場合にそれが叶う方法などはあるのでしょうか?
melian

2022/11/12 04:24

for ループを抜けてから to_csv() で書き込んでいましたので、最後のページのデータだけになっていたものと思います。何百ページ分などを出力したい場合は、データフレームをリストに溜めておいて、for ループの実行が完了したあとで一つにまとめて書き出すとよいかと。 df_all = [] for df in dfs:   :  df_all.append(df) df_all = pd.concat(df_all) df_all.to_csv('result.csv', index=None)
syoh0335

2022/11/12 04:45

melian様  解説ありがとうございます。 ”データフレームをリストに溜めておいて、for ループの実行が完了したあとで一つにまとめて書き出す”というところも、どうすればいいか頭でイメージすることができました。 ただ、ちょっとやってみたのですが、まだ1つにまとめて出力までには至らずです。 リストに溜めてまとめて出す方法は、melianさんが書いて頂いたコードを参考に自分で1度やってみようと思います。 親切に教えていただきありがとうございました。 ベストアンサーに選ばせていただきます。
melian

2022/11/12 05:05

ありがとうございます、回答に転記しておきました。
syoh0335

2022/11/12 05:57

今、触っていたら、また最後のページのみしか出力しなくなりました。。。 何度も申し訳ありませんが、ご助力お願い致します。 import pandas as pd import os from IPython.core.display import display import tabula ###PDFファイルパス path = 'data/〇〇〇.pdf' ###PDFの読み込み dfs = tabula.read_pdf(path, pages='all', lattice=True) ###読み込んだPDFを確認 # print(dfs[0]) # print(len(dfs), type(dfs), type(dfs[0]) ##型を調べる # print(dfs[0].dtypes) ###読み込んだPDFを整形 for df in (dfs): # # カラム変更 df.columns = ['取引日付', '取引内容', '出金', '入金', '残高'] #取引日付を'/'に統一 df['取引日付'] = df['取引日付'].replace('年', '/', regex=True) df['取引日付'] = df['取引日付'].replace('月', '/', regex=True) df['取引日付'] = df['取引日付'].replace('日', '', regex=True) #数値のカンマを消す df['出金'] = df['出金'].replace(',', '', regex=True) df['出金'] = df['出金'].replace(' ', '', regex=True) df['入金'] = df['入金'].replace(',', '', regex=True) df['入金'] = df['入金'].replace(' ', '', regex=True) df['残高'] = df['残高'].replace(',', '', regex=True) df['残高'] = df['残高'].replace(' ', '', regex=True) #円を消す df['出金'] = df['出金'].replace('円', '', regex=True) df['出金'] = df['出金'].replace(' ', '', regex=True) df['入金'] = df['入金'].replace('円', '', regex=True) df['入金'] = df['入金'].replace(' ', '', regex=True) df['残高'] = df['残高'].replace('円', '', regex=True) df['残高'] = df['残高'].replace(' ', '', regex=True) display(df) ###CSVへ出力 os.makedirs("SaveFolder", exist_ok=True) df.to_csv("SaveFolder\\result.csv", index=None) df.to_csv("SaveFolder\\result2.csv", index=None) df.to_csv("SaveFolder\\result3.csv", index=None)
melian

2022/11/12 06:22

回答に追記しましたので試してみて下さい。
syoh0335

2022/11/12 06:42

回答確認致しました。 私がやりたかったことが全て解決されましたので、感謝しかありません。 何度もありがとうございました。

回答1

0

ベストアンサー

※ コメントから転記

for ループを抜けてから to_csv() で書き込んでいましたので、最後のページのデータだけになっていたのでしょう。

何百ページ分などを出力したい場合は、データフレームをリストに溜めておいて、for ループの実行が完了した後で一つにまとめて書き出すとよいかと思います。

python

1df_all = [] 2for df in dfs: 3 : 4 df_all.append(df) 5 6df_all = pd.concat(df_all) 7df_all.to_csv('result.csv', index=None)

追記

具体的には以下の様に変更して試してみて下さい。

python

1# データフレーム保存用リスト 2df_all = [] 3 4###読み込んだPDFを整形 5for df in (dfs): 6 # カラム変更 7 df.columns = ['取引日付', '取引内容', '出金', '入金', '残高'] 8 9 #取引日付を'/'に統一 10 df['取引日付'] = df['取引日付'].replace('年', '/', regex=True) 11 df['取引日付'] = df['取引日付'].replace('月', '/', regex=True) 12 df['取引日付'] = df['取引日付'].replace('日', '', regex=True) 13 14 #数値のカンマを消す 15 df['出金'] = df['出金'].replace(',', '', regex=True) 16 df['出金'] = df['出金'].replace(' ', '', regex=True) 17 df['入金'] = df['入金'].replace(',', '', regex=True) 18 df['入金'] = df['入金'].replace(' ', '', regex=True) 19 df['残高'] = df['残高'].replace(',', '', regex=True) 20 df['残高'] = df['残高'].replace(' ', '', regex=True) 21 22 #円を消す 23 df['出金'] = df['出金'].replace('円', '', regex=True) 24 df['出金'] = df['出金'].replace(' ', '', regex=True) 25 df['入金'] = df['入金'].replace('円', '', regex=True) 26 df['入金'] = df['入金'].replace(' ', '', regex=True) 27 df['残高'] = df['残高'].replace('円', '', regex=True) 28 df['残高'] = df['残高'].replace(' ', '', regex=True) 29 30 display(df) 31 32 # リストに追加 33 df_all.append(df) 34 35 36# 全てのデータフレームを結合 37df_all = pd.concat(df_all) 38 39###CSVへ出力 40os.makedirs("SaveFolder", exist_ok=True) 41df_all.to_csv("SaveFolder\\result.csv", index=None)

投稿2022/11/12 05:05

編集2022/11/12 06:21
melian

総合スコア16236

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Python

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