Python:将pdf转换为csv(多行列)

Python:将pdf转换为csv(多行列),python,csv,pdf,multiline,tabula,Python,Csv,Pdf,Multiline,Tabula,我的CSV是: ,Élément,État général,Observations 0,ENTRÉE,Etat d'usage, 1,PORTES,Etat d'usage,Chaînette cassé Serrure du bas en mauvais état le système est cassé au niveau de la chaînette 2,ENTRÉE / PORTESENTRÉE / PORTES,, 3,Type de porte,,Porte blindée 4,

我的CSV是:

,Élément,État général,Observations
0,ENTRÉE,Etat d'usage,
1,PORTES,Etat d'usage,Chaînette cassé
Serrure du bas en mauvais état le système est
cassé au niveau de la chaînette
2,ENTRÉE / PORTESENTRÉE / PORTES,,
3,Type de porte,,Porte blindée
4,Poignée,,Bon état
5,Couleur,,Bois
但我想要这个:

,Élément,État général,Observations
0,ENTRÉE,Etat d'usage,
1,PORTES,Etat d'usage,Chaînette cassé; Serrure du bas en mauvais état le système ...
2,ENTRÉE / PORTESENTRÉE / PORTES,,
3,Type de porte,,Porte blindée
4,Poignée,,Bon état
5,Couleur,,Bois
我的代码只是将每个页面的一个或多个pdf转换为csv,如下所示:

import os
import io
import shutil
import tabula
import time

start_time = time.time()
path = './'

i=0
j=0

for( directory, subdirectories, file ) in os.walk(path):
    for f in file:
        if f.endswith('.pdf'):
                df = tabula.read_pdf(str(directory) + "/" + str(f), pages='all')
                i=0
                j+=1
                for curr_df in df:
                    i+=1
                    curr_df.to_csv('./' + str(directory) + '-' + str(i) + '.csv')

print("--- convert %d .PDF to %d .CSV in %s seconds ---" % (j, i, time.time() - start_time))

我的问题也是因为我不能逐案处理。我需要能够以相同的方式处理所有csv,您可以打开
csv
,读取行,并在前一行添加不以空(标题)或数字开头的字符串。然后将这些行写入新的
csv
文件:

with open('filename.csv') as f:
    text = [line.rstrip() for line in f.readlines()] #remove newline character with rstrip()
    lines = []
    for i in text:
        try:
            if i[0] ==',' or i[0].isnumeric():
                lines.append(i)
            else:
                lines[-1] = lines[-1] + "; " + i
        except:
            continue
            
with open('new_file.csv', mode='wt', encoding='utf-8') as newfile:
    newfile.write('\n'.join(lines)) # reinsert newline characters with '\n'.join()
要处理目录中的所有文件,我们可以将其放入函数中,并将目录中的所有文件提供给该函数:

import os as os
import glob as glob

def process_csv(filepath):
    with open(filepath) as f:
        text = [line.rstrip() for line in f.readlines()] #remove newline character with rstrip()
        lines = []
        for i in text:
            try:
                if i[0] ==',' or i[0].isnumeric():
                    lines.append(i)
                else:
                    lines[-1] = lines[-1] + "; " + i
            except:
                continue

    with open(os.path.basename(filepath) + '_fixed.csv', mode='wt', encoding='utf-8') as newfile:
        newfile.write('\n'.join(lines)) # reinsert newline characters with '\n'.join()
        print('fixed: ' + os.path.basename(filepath) + '_fixed.csv')

files = glob.glob('./*.csv') #use glob to create a list of filepath of csv files in a directory

for file in files: # loop through the list and feed each file to the function process_csv
    process_csv(file)

对于@SergeBallesta,这就是我所拥有的:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8 entries, 0 to 7
Data columns (total 4 columns):
 #   Column        Non-Null Count  Dtype 
---  ------        --------------  ----- 
 0   Unnamed: 0    8 non-null      object
 1   Élément       6 non-null      object
 2   État général  2 non-null      object
 3   Observations  4 non-null      object
dtypes: object(4)
memory usage: 384.0+ bytes
None
                                      Unnamed: 0                         Élément  État général     Observations
0                                              0                          ENTRÉE  Etat d'usage              NaN
1                                              1                          PORTES  Etat d'usage  Chaînette cassé
2  Serrure du bas en mauvais état le système est                             NaN           NaN              NaN
3                cassé au niveau de la chaînette                             NaN           NaN              NaN
4                                              2  ENTRÉE / PORTESENTRÉE / PORTES           NaN              NaN
5                                              3                   Type de porte           NaN    Porte blindée
6                                              4                         Poignée           NaN         Bon état
7                                              5                         Couleur           NaN             Bois

对于@Rjadriansen,我得到的错误是:

fixed: PDF-8.csv_fixed.csv
fixed: PDF-5.csv_fixed.csv
fixed: PDF-7.csv_fixed.csv
fixed: PDF-6.csv_fixed.csv
fixed: PDF-2.csv_fixed.csv
fixed: PDF-10.csv_fixed.csv
fixed: PDF-3.csv_fixed.csv
fixed: PDF-4.csv_fixed.csv
Traceback (most recent call last):
  File "corrCSV_v2.py", line 24, in <module>
    process_csv(file)
  File "corrCSV_v2.py", line 12, in process_csv
    if i[0] ==',' or i[0].isnumeric():
IndexError: string index out of range

我想这是因为空行

谢谢,它起作用了!您有处理多个文件的解决方案吗。例如:打开(./CSV/*.CSV)并将其保存在文件夹中。对不起,我是python新手。而且我刚刚意识到它创建了一个新的专栏,而我希望“Chaînette cassé;Serrure du bas en mauvaisétat le système…”也在同一个专栏中@Rjadriansenok,我已经更新了答案,以显示如何一次处理整个目录。顺便说一下,它不会创建新列。它将句子部分与
链接如所需输出中所示。但是列之间用
分隔。通过使用
pd.read\u csv('filename.csv')
pandas
中加载文件,您可以自己查看。非常感谢@rjadriansen,这对我帮助很大。但是,我的一些.csv仍然存在问题。我在上面发布了错误OK,我在答案中插入了一个
try except
,它将管理空行。我无法理解pandas
to_csv
如何生成错误的csv文件。多行字段在CSV文件中很常见,但它们应该包含在引号中。熊猫能否正确读取带有pd.read_csv的那些文件?目前,它看起来像熊猫中的一个bug,这很奇怪……Hello@SergeBallesta我没有使用panda,但Tablea你认为这是我的错误吗?Tablea
read\u pdf
通常会返回熊猫数据帧列表。而
to_csv
是pandas
DataFrame
的一种方法,通常会生成性能良好的文件。要键入以加载带有熊猫的csv文件,您可以使用
将熊猫作为pd导入
df=pd.read_csv('/path/To/file.csv')
打印(df.info())
打印(df)
并报告您得到的结果。我得到一个错误,我将其显示在下面。这将尝试使用熊猫read_csv加载PDF文件。我的意思是将
…生成的CSV文件加载到\u CSV(…)
对不起,我觉得太愚蠢了。。。我更正了我的答案。
fixed: PDF-8.csv_fixed.csv
fixed: PDF-5.csv_fixed.csv
fixed: PDF-7.csv_fixed.csv
fixed: PDF-6.csv_fixed.csv
fixed: PDF-2.csv_fixed.csv
fixed: PDF-10.csv_fixed.csv
fixed: PDF-3.csv_fixed.csv
fixed: PDF-4.csv_fixed.csv
Traceback (most recent call last):
  File "corrCSV_v2.py", line 24, in <module>
    process_csv(file)
  File "corrCSV_v2.py", line 12, in process_csv
    if i[0] ==',' or i[0].isnumeric():
IndexError: string index out of range
,Élément,État général,Observations
0,CUISINE,Etat d'usage,
1,CUISINECUISINE 15CUISINE 18

CUISINE 19,,