[PYTHON] Convertissez l'historique d'utilisation de Suica mobile au format PDF au format pandas Data Frame avec tabula-py

"Création d'un service qui modifie l'historique d'utilisation de Suica mobile afin qu'il puisse être facilement utilisé pour le règlement des dépenses" La dernière fois, j'ai créé un environnement d'exécution avec Docker Cliquez ici pour le produit fini https://www.mobilesuica.work

Environnement d'exploitation

Comme il est difficile de préparer l'environnement sous Windows, j'ai configuré et exécuté un conteneur qui exécute Python avec Docker

tabula-py tabula-py Tout d'abord, j'ai essayé cela facilement

test.py


import tabula
import pandas as pd
df = tabula.read_pdf('a.pdf')
print(df.head())

Malheureusement c'était une erreur

AttributeError: 'list' object has no attribute 'head'

Apparemment, il est retourné dans un tableau Si oui, dois-je le faire?

test.py


df = tabula.read_pdf('a.pdf')
print(df[0].head())

Cela a été fait (le nom de la station résultante a changé)

Type de date Type de station utilisée.1 Station utilisée.1 Différence d'équilibre
0 2 6 Répéter NaN NaN NaN\9,753   NaN
2 2 7 Entrer à Tokyo Sortie Yokohama\9,573  -180
3 2 7 Entrer à Yokohama Sortie Tokyo\9,393  -180

Plusieurs pages à la fois

Par défaut, seule la première page est utilisée, donc ajoutez pages = 'all' et combinez les deux pages. L'historique d'utilisation maximum de Mobile Suica est de 100, et s'il est différé, il y en a 101, et s'il est converti en PDF, il fera jusqu'à 2 pages.

test.py


df = tabula.read_pdf('a.pdf',pages='all')
for i in range(len(df)):
    print(f"{i+1}Sur la page{len(df[i])}Il y a une ligne")

Résultat d'exécution

(app-root) bash-4.2# python3 test.py
Il y a 51 lignes sur une page
Il y a 50 lignes sur 2 pages

Vous pouvez voir que la première page a une ligne de plus pour "différé". Comme il est difficile de gérer s'ils sont séparés, nous utiliserons un DataFrmae. Utilisez concat.

test.py


df = tabula.read_pdf('a.pdf',pages='all')
d = pd.concat(df,ignore_index=True)
print(f"{len(d)}Il y a une ligne")

Résultat d'exécution

(app-root) bash-4.2# python3 test.py
Il y a 101 lignes

** ignore_index = True **, mais si vous ne l'incluez pas, l'index ne sera pas un numéro de série correctement. Comparons.

ignore_index = Vrai Aucun L'index revient à 0 à la limite entre les 1ère et 2ème pages

50 3 4 Entrer à Tokyo Sortie Yokohama\9,443    -180
0 3 5 Cash NaN NaN NaN\9,543     100

ignore_index = True Oui C'est un numéro de série tel quel

50 3 4 Entrer à Tokyo Sortie Yokohama\9,443    -180
51 3 5 Cash NaN NaN NaN\9,543     100

Si vous allez jusque-là, vous pouvez faire de même avec plusieurs fichiers. Il y a aussi convert_into_by_batch dans tabula-py, mais c'est un peu difficile à utiliser car c'est comme spécifier un répertoire et collecter les fichiers PDF sous celui-ci. (Comme je n'avais qu'un seul historique d'utilisation, j'ai lu le même fichier plusieurs fois)

test.py


fileList = ['a.pdf','a.pdf','a.pdf']
dfList = []
for fileName in fileList:
    df = tabula.read_pdf(fileName,pages='all')
    for i in range(len(df)):
        dfList.append(df[i])
d = pd.concat(dfList,ignore_index=True)
print(f"{len(d)}Il y a une ligne")

Résultat d'exécution

(app-root) bash-4.2# python3 test.py
Il y a 303 lignes

Jusqu'à présent, j'ai remarqué qu'il y avait une légère différence entre la première et la deuxième page.

Charger une partie sur la première page
24 2 21 Espèces NaN NaN NaN\9,883    +100
Charge partie sur la deuxième page
78 3 21 Espèces NaN NaN NaN\10,317     100

Il n'y a pas de "+" sur la deuxième page. Je peux le faire sans aucun problème en termes de traitement des données, mais ça fait du mal. Quand je l'ai recherché, c'était la différence entre le reconnaître comme un nombre (deuxième page) et le reconnaître comme un caractère (première page).

14 2 15 Bus etc. OKK NaN NaN\9,103  -2,000

S'il dépasse 3 chiffres, le séparateur de mille (,) sera inclus, il semble donc que toutes les pages soient reconnues comme des caractères. La page 2 a été reconnue comme un nombre parce qu'elle n'y figurait pas (toutes à moins de 3 chiffres). Puisqu'il est plus pratique de le prendre tel quel en tant que caractère, j'ai cherché avec des pandas et j'ai trouvé que ** dtype = 'object' ** devrait être utilisé. tabula-py est un excellent moyen de transmettre les options de pandas telles quelles. La forme finale est la suivante.

test.py


fileList = ['a.pdf','a.pdf','a.pdf']
dfList = []
for fileName in fileList:
    df = tabula.read_pdf(fileName,pages='all',pandas_options={'dtype':'object'})
    for i in range(len(df)):
        dfList.append(df[i])
d = pd.concat(dfList,ignore_index=True)

C'est incroyable que vous puissiez déposer un tableau PDF dans un DataFrame avec juste cela.

Recommended Posts

Convertissez l'historique d'utilisation de Suica mobile au format PDF au format pandas Data Frame avec tabula-py
Convertir 202003 en 2020-03 avec les pandas
Comment convertir des données détenues horizontalement en données détenues verticalement avec des pandas
Convertir un PDF en image avec ImageMagick
Convertir les données au format XML en données au format txt (yolov3)
Convertir de PDF en CSV avec pdfplumber
Convertir des données Excel en JSON avec python
Convertir les données de la grille en données contenant des lignes (?) À l'aide de pandas
Convertissez des données FX 1 minute en données 5 minutes avec Python
Convertir un PDF joint en courrier électronique au format texte
Essayez de convertir en données ordonnées avec les pandas
Convertir des fichiers PDF en fichiers PNG avec GIMP
Essayez d'agréger les données de musique doujin avec des pandas
Convertissez les données avec la forme (nombre de données, 1) en (nombre de données,) avec numpy.
Convertir un PDF en image (JPEG / PNG) avec Python
Convertir les données au format json en txt (en utilisant yolo)
Transformez les données de vacances en une trame de données avec les pandas
Convertir une chaîne au format de liste caractère par caractère avec python
Enregistrez les données pandas dans des actifs de données au format Excel avec Cloud Pak for Data (Watson Studio)
J'ai essayé de créer un cadre de données pandas en grattant les informations de rappel d'aliments avec Python
Je veux donner un group_id à une trame de données pandas
Convertissez l'image au format .zip en PDF avec Python
Comment extraire des données qui ne manquent pas de valeur nan avec des pandas
Comment convertir un fichier JSON en fichier CSV avec Python Pandas
Convertissez les variables numériques en variables catégorielles avec les pandas en définissant un seuil
Comment extraire des données qui ne manquent pas de valeur nan avec des pandas
Visualisation des données avec les pandas
Manipulation des données avec les Pandas!
Mélangez les données avec les pandas
Comment sortir un document au format pdf avec Sphinx
Ingéniosité pour gérer les données avec Pandas de manière à économiser la mémoire
Convertissez des images numérisées déformées en PDF avec Pillow et PyPDF
Convertissez les données météorologiques au format GRIB2 qui ne peuvent pas être ouvertes avec pygrib en netCDF et visualisez-les