前提
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
df.to_csv("result.csv", index=None)
を for ループの内部に入れて、CSVファイルの名前を適宜変更する必要があります。
melian様 前回に引き続きコメントありがとうございます。
forループ内に"df.to_csv("result.csv", index=None)"を入れ、CSVファイルの名前を変えたコードを3行追加したら、3ページ共出力することができました。
今まで1行のみしか書いていなかったので、上書きされていたということなのでしょうか?
この場合、今は数ページなので適宜変更することは手間ではないですが、もし何百ページ分などを出力したい場合にそれが叶う方法などはあるのでしょうか?
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)
melian様 
解説ありがとうございます。
”データフレームをリストに溜めておいて、for ループの実行が完了したあとで一つにまとめて書き出す”というところも、どうすればいいか頭でイメージすることができました。
ただ、ちょっとやってみたのですが、まだ1つにまとめて出力までには至らずです。
リストに溜めてまとめて出す方法は、melianさんが書いて頂いたコードを参考に自分で1度やってみようと思います。
親切に教えていただきありがとうございました。
ベストアンサーに選ばせていただきます。
ありがとうございます、回答に転記しておきました。
今、触っていたら、また最後のページのみしか出力しなくなりました。。。
何度も申し訳ありませんが、ご助力お願い致します。
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)
回答に追記しましたので試してみて下さい。
回答確認致しました。
私がやりたかったことが全て解決されましたので、感謝しかありません。
何度もありがとうございました。

回答1件
あなたの回答
tips
プレビュー

