我是为了写论文所以学习了以下Python。要实现的目的是:逐一读取文件夹中各个年报pdf中“经营情况讨论与分析”章节。将该章节中包含一些特定关键字的句子全部筛选出来,然后评价筛选出来句子语调积极程度,并将结果输出为Excel,Excel中要包含的内容包括公司名称,年份,语调积极程度评分。代码没有报错可以正常跑,但秒跑完,然后输出的result是一个空的Excel,请问问题出在了哪里呢?因为是目的性很强的去学习Python,所以对很多理论知识都一知半解,还请各位能帮我解决一下这个问题,谢谢!
import os
import re
import pandas as pd
from PyPDF2 import PdfFileReader
# 定义关键字列表
keywords = ['增长', '提高', '增加', '扩大', '优化', '改善', '创新', '领先', '占据市场', '提升', '强化', '突破', '拓展', '加强', '提升']
# 定义函数,用于读取pdf文件中的指定章节
def read_pdf_section(pdf_path):
with open(pdf_path, 'rb') as f:
pdf = PdfFileReader(f)
for page in pdf.pages:
text = page.extractText()
# 查找“经营情况讨论与分析”章节
match = re.search(r'经营情况讨论与分析', text)
if match:
# 获取章节所在页码
page_num = pdf.pages.index(page)
# 查找章节结束位置
end_match = re.search(r'[\n\s]*[\d一二三四五六七八九十]+[\n\s]*年度报告', text[match.end():])
if end_match:
end_pos = match.end() + end_match.start()
else:
end_pos = len(text)
# 返回章节内容
return text[match.end():end_pos], page_num
# 如果未找到指定章节,则返回空字符串和-1
return '', -1
# 定义函数,用于评价句子语调积极程度
def evaluate_tone(sentence):
score = 0
for keyword in keywords:
if keyword in sentence:
score += 1
return score
# 定义函数,用于处理单个pdf文件
def process_pdf(pdf_path):
# 读取pdf文件中的指定章节
section, page_num = read_pdf_section(pdf_path)
if page_num == -1:
return None
# 将章节内容按句子分割
sentences = re.split(r'[。!?]', section)
# 筛选包含关键字的句子
filtered_sentences = [sentence.strip() for sentence in sentences if any(keyword in sentence for keyword in keywords)]
# 评价句子语调积极程度
scores = [evaluate_tone(sentence) for sentence in filtered_sentences]
# 获取公司名称和年份
company_name = os.path.basename(os.path.dirname(pdf_path))
year = re.search(r'(\d{4})年度报告', section).group(1)
# 构造结果字典
result = {'公司名称': company_name, '年份': year, '语调积极程度评分': sum(scores) / len(scores)}
return result
# 定义函数,用于处理整个文件夹
def process_folder(folder_path):
results = []
for file_name in os.listdir(folder_path):
if file_name.endswith('.pdf'):
file_path = os.path.join(folder_path, file_name)
result = process_pdf(file_path)
if result:
results.append(result)
# 将结果转换为DataFrame并输出为Excel文件
df = pd.DataFrame(results)
df.to_excel('result.xlsx', index=False)
# 调用函数,处理指定文件夹
process_folder('D:\上市公司年报')
你好,你的代码比较多,我只是大概看了下。
问题出在pd.DataFrame(results)这句代码里的results的数据类型不对。
这边你的results是一个list,而每个list的元素是一个dict。这不是pd.DataFrame()能够接受的数据类型。
pd.DataFrame()接受4种数据类型,ndarray, Series, DataFrame, dict。
而你的results是一个list,不在四种可接受的四种数据类型之列, 你需要对results做一个类型转变。
data = {
'公司名称': [],
'年份': [],
'语调积极程度评分': []
}
for result in results:
data['公司名称'].append(result['公司名称'])
data['年份'].append(result['年份'])
data['语调积极程度评分'].append(result['公司名称'])
不知道你这个问题是否已经解决, 如果还没有解决的话:以下代码纯粹手写,未参考其他人代码,如果问题,请不吝赐教。
1,计算信息熵的函数
import numpy as np
# 计算信息熵
# data:like np.array
# data.shape=(num_data,data_features+1) 即属性与label放一起了
def entropy(data,num_class):
class_set=list(set(data[:,-1]))
result=0
length=len(data)
# 这里修改一下,不使用num_class
for i in range(len(class_set)):
l=len(data[data[:,-1]==class_set[i]])
p=l/length
# 防止某类未出现,概率为0
if p>0:
result-=p*np.log2(p)
return result
Python学习qq群:10667510,送全套爬虫学习资料与教程~
2,计算增益及属性a的固有值(IV)
# 计算不同属性的信息增益
# detail_features:特征构成的list,每个特征的可取值构成list元素,即也是list
def calculate_gain(data,detail_features,num_class):
'''返回各属性对应的信息增益及平均值'''
result=[]
ent_data=entropy(data,num_class)
for i in range(len(detail_features)):
res=ent_data
for j in range(len(detail_features[i])):
# 有问题?
part_data=data[data[:,i]==detail_features[i][j]]
length=len(part_data)
res-=length*entropy(part_data,num_class)/len(data)
result.append(res)
return result,np.array(result).mean()
# 计算某个属性的固有值
def IVa(data,attr_index):
attr_values=list(set(data[:,attr_index]))
v=len(attr_values)
res=0
for i in range(v):
part_data=data[data[:,attr_index]==attr_values[i]]
p=len(part_data)/len(data)
res-=p*np.log2(p)
return res
Python学习qq群:10667510,送全套爬虫学习资料与教程~
3,构建节点类,以便构建树
class Node:
def __init__(self,key,childs):
self.childs=[]
self.key=key
def add_node(self,node):
self.childs.append(node)
4,构建树
# 判断数据是否在所有属性的取值都一样,以致无法划分
def same_data(data,attrs):
for i in range(len(attrs)):
if len(set(data[:,i]))>1:
return False
return True
# attrs:属性的具体形式
def create_tree(data,attrs,num_class,root):
# 注意这里3个退出条件
# 1,如果数据为空,不能划分,此时这个叶节点不知标记为哪个分类了
if len(data)==0:
return
# 2,如果属性集为空,或所有样本在所有属性的取值相同,无法划分,返回样本最多的类别
if len(attrs)==0 or same_data(data,attrs):
class_set=list(set(data[:,-1]))
max_len=0
index=0
for i in range(len(class_set)):
if len(data[data[:,-1]==class_set[i]])>max_len:
max_len=len(data[data[:,-1]==class_set[i]])
index=i
root.key=root.key+class_set[index]
return
# 3,如果当前节点包含同一类的样本,无需划分
if len(set(data[:,-1]))==1:
root.key=root.key+data[0,-1]
return
ent=entropy(data,num_class)
gain_result,mean=calculate_gain(data,attrs,num_class)
max=0
max_index=-1
# 求增益率最大
for i in range(len(gain_result)):
if gain_result[i]>=mean:
iva=IVa(data,i)
if gain_result[i]/iva>max:
max=gain_result[i]/iva
max_index=i
for j in range(len(attrs[max_index])):
part_data=data[data[:,max_index]==attrs[max_index][j]]
# 删除该列特征
part_data=np.delete(part_data,max_index,axis=1)
# 添加节点
root.add_node(Node(key=attrs[max_index][j],childs=[]))
# 删除某一类已判断属性
new_attrs=attrs[0:max_index]
new_attrs.extend(attrs[max_index+1:])
create_tree(part_data,new_attrs,num_class,root.childs[j])
Python学习qq群:10667510,送全套爬虫学习资料与教程~
5,使用西瓜数据集2.0测试,数据这里就手写了,比较少
def createDataSet(): """ 创建测试的数据集 :return: """ dataSet = [ # 1 ['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'], # 2 ['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '好瓜'], # 3 ['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'], # 4 ['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '好瓜'], # 5 ['浅白', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'], # 6 ['青绿', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '好瓜'], # 7 ['乌黑', '稍蜷', '浊响', '稍糊', '稍凹', '软粘', '好瓜'], # 8 ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '硬滑', '好瓜'], # ---------------------------------------------------- # 9 ['乌黑', '稍蜷', '沉闷', '稍糊', '稍凹', '硬滑', '坏瓜'], # 10 ['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', '坏瓜'], # 11 ['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', '坏瓜'], # 12 ['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', '坏瓜'], # 13 ['青绿', '稍蜷', '浊响', '稍糊', '凹陷', '硬滑', '坏瓜'], # 14 ['浅白', '稍蜷', '沉闷', '稍糊', '凹陷', '硬滑', '坏瓜'], # 15 ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '坏瓜'], # 16 ['浅白', '蜷缩', '浊响', '模糊', '平坦', '硬滑', '坏瓜'], # 17 ['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', '坏瓜'] ] # 特征值列表 labels = ['色泽', '根蒂', '敲击', '纹理', '脐部', '触感'] # 特征对应的所有可能的情况
labels_full = []
for i in range(len(labels)):
items=[item[i] for item in dataSet]
uniqueLabel = set(items)
labels_full.append(list(uniqueLabel))
return np.array(dataSet), labels, labels_full
Python学习qq群:10667510,送全套爬虫学习资料与教程~
6,开始构建树
dataset,labels,labels_full=createDataSet()
root=Node('',[])
create_tree(dataset, labels_full, 2, root)
Python学习qq群:10667510,送全套爬虫学习资料与教程~
7,打印树结构
def print_root(n,root):print(n,root.key)
for node in root.childs:
print_root(n+1,node)
print_root(0,root)
Python学习qq群:10667510,送全套爬虫学习资料与教程~
打印结果为:数字表示层次
0 1 模糊坏瓜 1 稍糊 2 硬滑坏瓜 2 软粘好瓜 1 清晰 2 硬滑好瓜 2 软粘 3 青绿 4 稍蜷好瓜 4 蜷缩 4 硬挺坏瓜 3 乌黑坏瓜 3 浅白
8,绘制树形结构,这里我就手动绘制了。图中有2个叶节点为空白,即模型不知道该推测其为好瓜还是坏瓜。这里我暂时没有好的思路解决,只能随机处理?