首页 > 解决方案 > 熊猫加入多行文本

问题描述

我正在使用 tabula-py 阅读 pdf。

from tabula import read_pdf
pdf_path = "/home/user/test.pdf"
df = read_pdf(pdf_path, pages='all', silent='True')

不幸的是,我的 pdf 格式不一致,其中一列的文本被分成多行,如下所示:

Date        Comment      post_id
----------------------------------
03/07/20    Comment 1           1
03/07/20    Comment b 1         2
NaN         Comment b 2       NaN
NaN         Comment b 3       NaN
04/07/20    Comment c 1         3
NaN         Comment c 1       NaN

如何将数据框格式化为如下所示

Date        Comment                             post_id
-------------------------------------------------------------
03/07/20    Comment 1                                 1
03/07/20    Comment b 1 Comment b 2 Comment b 3       2
04/07/20    Comment c 1 Comment c 1                   3

更多的单行列按预期工作。

标签: pythonpandasdataframe

解决方案


因为有重复的值,所以使用累积和传递的测试非缺失Date值创建助手,并通过聚合和传递:SeriesSeries.cumsumGroupBy.aggGroupBy.firstjoin

g = df['Date'].notna().cumsum()

df = df.groupby(g).agg({'Date':'first', 'Comment': ' '.join}).reset_index(drop=True)
print (df)
       Date                              Comment
0  03/07/20                            Comment 1
1  03/07/20  Comment b 1 Comment b 2 Comment b 3
2  04/07/20              Comment c 1 Comment c 1

对于首先聚合所有列的一般解决方案,没有Comment可能生成字典动态:

print (df.columns)
Index(['Date', 'Comment', 'post_id'], dtype='object')

g = df['Date'].notna().cumsum()

d = dict.fromkeys(df.columns.difference(['Comment']), 'first')
d['Comment'] = ' '.join
print (d)
{'Date': 'first', 'post_id': 'first', 
  'Comment': <built-in method join of str object at 0x00000000028761B0>}


df = df.groupby(g).agg(d).reset_index(drop=True)
print (df)
       Date  post_id                              Comment
0  03/07/20      1.0                            Comment 1
1  03/07/20      2.0  Comment b 1 Comment b 2 Comment b 3
2  04/07/20      3.0              Comment c 1 Comment c 1

Comment与输出DataFrame中相同顺序的列的字典中的覆盖键类似的想法:

print (df.columns)
Index(['Date', 'Comment', 'post_id'], dtype='object')

g = df['Date'].notna().cumsum()

d = dict.fromkeys(df.columns, 'first')
d['Comment'] = ' '.join
print (d)
{'Date': 'first', 
 'Comment': <built-in method join of str object at 0x00000000028761B0>, 
 'post_id': 'first'}

df = df.groupby(g).agg(d).reset_index(drop=True)
print (df)
       Date                              Comment  post_id
0  03/07/20                            Comment 1      1.0
1  03/07/20  Comment b 1 Comment b 2 Comment b 3      2.0
2  04/07/20              Comment c 1 Comment c 1      3.0

推荐阅读