【Python代碼】谷歌專利CSV處理函數

以下是一個重構后的高可用、可配置、低耦合的專利CSV處理函數,包含清晰的注釋和結構:

import csv
import pandas as pd
from datetime import datetime
import os
from typing import List, Dict, Any, Optional, Tuple
import logging# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)class PatentProcessor:"""專利數據處理器"""def __init__(self, config: Optional[Dict[str, Any]] = None):"""初始化專利處理器Args:config: 配置字典,包含處理選項"""self.config = config or self.get_default_config()@staticmethoddef get_default_config() -> Dict[str, Any]:"""獲取默認配置"""return {'required_columns': ['id', 'inventor/author', 'title', 'priority date'],'author_column': 'inventor/author','split_separator': ',','filter_condition': None,  # 例如: {'column': 'assignee', 'value': '百度', 'case_sensitive': False}'output_columns': ['author', 'value', 'id', 'title_list', 'priority_date_list', 'start_year', 'end_year'],'encoding': 'utf-8'}def load_csv_data(self, csv_filepath: str) -> Optional[pd.DataFrame]:"""加載CSV文件數據Args:csv_filepath: CSV文件路徑Returns:pandas DataFrame 或 None(如果加載失敗)"""try:data = []with open(csv_filepath, encoding=self.config['encoding']) as f:reader = csv.reader(f)for row in reader:data.append(row)if len(data) < 2:logger.warning(f"File {csv_filepath} has insufficient data rows")return None# 使用第二行作為列名,第三行開始作為數據df = pd.DataFrame(data[2:], columns=data[1])logger.info(f"Successfully loaded CSV file: {csv_filepath}")return dfexcept FileNotFoundError:logger.error(f"Error: The file {csv_filepath} does not exist.")except Exception as e:logger.error(f"An unexpected error occurred while loading {csv_filepath}: {e}")return Nonedef apply_filters(self, df: pd.DataFrame) -> pd.DataFrame:"""應用數據過濾條件Args:df: 輸入DataFrameReturns:過濾后的DataFrame"""filter_condition = self.config.get('filter_condition')if filter_condition:column = filter_condition['column']value = filter_condition['value']case_sensitive = filter_condition.get('case_sensitive', False)if column in df.columns:if case_sensitive:df = df[df[column].str.contains(value, na=False)]else:df = df[df[column].str.contains(value, case=False, na=False)]logger.info(f"Applied filter: {filter_condition}")return dfdef convert_to_excel(self, df: pd.DataFrame, csv_filepath: str) -> str:"""將DataFrame轉換為Excel文件Args:df: 輸入DataFramecsv_filepath: 原始CSV文件路徑(用于生成輸出路徑)Returns:生成的Excel文件路徑"""try:excel_filepath = csv_filepath.replace('.csv', '.xlsx')df.to_excel(excel_filepath, index=False)logger.info(f"CSV file has been converted to Excel: {excel_filepath}")return excel_filepathexcept Exception as e:logger.error(f"Error converting to Excel: {e}")return ""def process_authors(self, df: pd.DataFrame) -> pd.DataFrame:"""處理作者數據,進行統計和分析Args:df: 包含專利數據的DataFrameReturns:作者統計DataFrame"""# 選擇需要的列required_cols = self.config['required_columns']missing_cols = [col for col in required_cols if col not in df.columns]if missing_cols:logger.warning(f"Missing columns: {missing_cols}. Available columns: {list(df.columns)}")required_cols = [col for col in required_cols if col in df.columns]df = df[required_cols].copy()# 分割作者列author_col = self.config['author_column']if author_col in df.columns:df[author_col] = df[author_col].str.split(self.config['split_separator'])df = df.explode(author_col)df[author_col] = df[author_col].str.strip()# 統計作者出現次數author_counts = df[author_col].value_counts()new_df = pd.DataFrame({'author': author_counts.index,'value': author_counts.values})# 修復:使用列表推導式而不是直接賦值new_df['id'] = [df[df[author_col] == author]['id'].tolist() for author in new_df['author']]new_df['title_list'] = [df[df[author_col] == author]['title'].tolist() for author in new_df['author']]if 'priority date' in df.columns:new_df['priority_date_list'] = [df[df[author_col] == author]['priority date'].tolist() for author in new_df['author']]# 計算開始和結束年份date_ranges = [self.calculate_date_range(dates) for dates in new_df['priority_date_list']]new_df['start_year'] = [start for start, _ in date_ranges]new_df['end_year'] = [end for _, end in date_ranges]return new_df@staticmethoddef calculate_date_range(date_list: List[str]) -> Tuple[Optional[int], Optional[int]]:"""計算日期列表的開始和結束年份Args:date_list: 日期字符串列表Returns:(開始年份, 結束年份) 元組"""valid_dates = []for date_str in date_list:if pd.notna(date_str) and date_str.strip():try:# 嘗試多種日期格式date_obj = datetime.strptime(date_str.strip(), '%Y-%m-%d')valid_dates.append(date_obj)except ValueError:try:date_obj = datetime.strptime(date_str.strip(), '%Y/%m/%d')valid_dates.append(date_obj)except ValueError:# 如果無法解析日期,跳過continueif not valid_dates:return None, Nonemin_date = min(valid_dates)max_date = max(valid_dates)return min_date.year, max_date.yeardef save_author_stats(self, author_df: pd.DataFrame, csv_filepath: str) -> str:"""保存作者統計結果Args:author_df: 作者統計DataFramecsv_filepath: 原始CSV文件路徑(用于生成輸出路徑)Returns:生成的統計文件路徑"""try:rank_excel_filepath = csv_filepath.replace('.csv', '_rank.xlsx')# 只保存配置中指定的列output_cols = [col for col in self.config['output_columns'] if col in author_df.columns]author_df[output_cols].to_excel(rank_excel_filepath, index=False)logger.info(f"Author statistics saved: {rank_excel_filepath}")return rank_excel_filepathexcept Exception as e:logger.error(f"Error saving author statistics: {e}")return ""def process_patent_file(self, csv_filepath: str) -> Dict[str, str]:"""處理單個專利CSV文件Args:csv_filepath: CSV文件路徑Returns:包含輸出文件路徑的字典"""results = {'original_file': csv_filepath}# 1. 加載數據df = self.load_csv_data(csv_filepath)if df is None or df.empty:return results# 2. 應用過濾條件df = self.apply_filters(df)# 3. 轉換為Excelexcel_path = self.convert_to_excel(df, csv_filepath)results['excel_file'] = excel_path# 4. 處理作者數據author_df = self.process_authors(df)# 5. 保存作者統計stats_path = self.save_author_stats(author_df, csv_filepath)results['stats_file'] = stats_pathreturn results# 使用示例
def process_patents_folder(folder_path: str, file_list: List[str], config: Optional[Dict[str, Any]] = None):"""處理文件夾中的多個專利CSV文件Args:folder_path: 文件夾路徑file_list: 要處理的文件列表config: 處理配置"""processor = PatentProcessor(config)for filename in file_list:file_path = os.path.join(folder_path, filename)logger.info(f"Processing file: {filename}")try:results = processor.process_patent_file(file_path)logger.info(f"Completed processing: {filename}")logger.info(f"Results: {results}")except Exception as e:logger.error(f"Error processing {filename}: {e}")# 配置示例
CUSTOM_CONFIG = {'required_columns': ['id', 'inventor/author', 'title', 'priority date'],'author_column': 'inventor/author','split_separator': ',','filter_condition': None,  # 例如: {'column': 'assignee', 'value': 'Google', 'case_sensitive': False}'output_columns': ['author', 'value', 'id', 'title_list', 'priority_date_list', 'start_year', 'end_year'],'encoding': 'utf-8'}if __name__ == "__main__":# 使用示例folder = r'E:files\patents'gp_files = ["gp-search-google.csv",]# 使用默認配置處理文件process_patents_folder(folder, gp_files)# 使用自定義配置處理文件# process_patents_folder(folder, gp_files, CUSTOM_CONFIG)

這個重構版本具有以下優點:

  1. 模塊化設計:將功能拆分為多個獨立的方法,每個方法只負責一個明確的任務
  2. 可配置性:通過配置字典可以靈活調整處理參數
  3. 錯誤處理:完善的異常處理和日志記錄
  4. 類型提示:添加了類型提示,提高代碼可讀性和可維護性
  5. 靈活性:支持自定義過濾條件、輸出列等
  6. 可擴展性:易于添加新的處理功能或修改現有邏輯
  7. 清晰的文檔:每個方法都有詳細的文檔字符串說明參數和返回值

使用方法:

# 簡單使用
processor = PatentProcessor()
results = processor.process_patent_file('path/to/patents.csv')# 自定義配置使用
config = {'filter_condition': {'column': 'assignee', 'value': 'Google', 'case_sensitive': False},'required_columns': ['id', 'inventor/author', 'title', 'priority date']
}
processor = PatentProcessor(config)
results = processor.process_patent_file('path/to/patents.csv')

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/919741.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/919741.shtml
英文地址,請注明出處:http://en.pswp.cn/news/919741.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

3-2〔OSCP ? 研記〕? WEB應用攻擊?WEB安全防護體系

鄭重聲明&#xff1a; 本文所有安全知識與技術&#xff0c;僅用于探討、研究及學習&#xff0c;嚴禁用于違反國家法律法規的非法活動。對于因不當使用相關內容造成的任何損失或法律責任&#xff0c;本人不承擔任何責任。 如需轉載&#xff0c;請注明出處且不得用于商業盈利。 …

PCIe 5.0相比頂級PCIe 4.0有何提升?

還在為PCIe 4.0固態硬盤那7000MB/s的速度沾沾自喜&#xff1f;醒醒&#xff0c;朋友。當很多人還在討論PCIe 4.0是否“性能過剩”時&#xff0c;真正面向未來的PCIe 5.0已經帶著碾壓級的實力&#xff0c;來到了我們面前。這不是一次常規的“升級”&#xff0c;更不是英特爾式的…

23種設計模式——適配器模式(Adapter)?詳解

?作者簡介&#xff1a;大家好&#xff0c;我是 Meteors., 向往著更加簡潔高效的代碼寫法與編程方式&#xff0c;持續分享Java技術內容。 &#x1f34e;個人主頁&#xff1a;Meteors.的博客 &#x1f49e;當前專欄&#xff1a; 設計模式 ?特色專欄&#xff1a; 知識分享 &…

Vue3源碼reactivity響應式篇之Reactive

概覽 vue3中reactive用于將普通對象轉換為響應式對象&#xff0c;它的實現原理是通過Proxy和Reflect來實現的。具體的實現文件參見packages\reactivity\src\reactive.ts。本文會介紹reactive的相關api如下&#xff1a; reactive&#xff1a;將普通對象轉換為響應式對象readonly…

初識數據結構——Map和Set:哈希表與二叉搜索樹的魔法對決

數據結構專欄 ?(click) 大家好&#xff01;我是你們的老朋友——想不明白的過度思考者&#xff01;今天我們要一起探索Java中兩個神奇的數據結構&#xff1a;Map和Set&#xff01;準備好了嗎&#xff1f;讓我們開始這場魔法之旅吧&#xff01;&#x1f3a9; &#x1f3af; 先…

Unreal Engine UStaticMeshComponent

UnrealUnreal Engine - UStaticMeshComponent&#x1f3db; 定義&#x1f3db; 類繼承? 關鍵特性?? 常見配置&#x1f6e0;? 使用方法&#x1f4da; 在 C 中使用&#x1f4da; 在藍圖中使用&#x1f3ae; 典型應用場景&#x1f4da; 常見子類與用途&#x1f4dd; 小結Unrea…

demo 汽車之家(渲染-篩選-排序-模塊抽離數據)

效果圖展示&#xff1a;代碼截圖注釋詳情實現筆記總體目標&#xff08;按需求點對照代碼&#xff09;數據模塊化、整體渲染框架、篩選/排序的高亮與行為&#xff0c;全部已在 Index.ets CarData.ets 落地。下面按圖片需求 2~4 點逐條總結&#xff0c;并給出關鍵代碼定位與“為…

雙重機器學習DML介紹

本文參考&#xff1a; [1]文心一言回答&#xff1b; 一、核心原理與數學框架 雙重機器學習&#xff08;Double Machine Learning, DML&#xff09;由Chernozhukov等學者于2018年提出&#xff0c;是一種結合機器學習與傳統計量經濟學的因果推斷框架。其核心目標是在高維數據和非…

【圖像算法 - 21】慧眼識蟲:基于深度學習與OpenCV的農田害蟲智能識別系統

摘要&#xff1a; 在現代農業生產中&#xff0c;病蟲害是影響作物產量和品質的關鍵因素之一。傳統的害蟲識別依賴人工巡查&#xff0c;效率低、成本高且易出錯。本文將介紹如何利用深度學習與OpenCV構建一套高效的農田害蟲智能識別系統。該系統能夠自動識別10類常見農業害蟲&a…

循環神經網絡實戰:GRU 對比 LSTM 的中文情感分析(三)

循環神經網絡實戰&#xff1a;GRU 對比 LSTM 的中文情感分析&#xff08;三&#xff09; 文章目錄循環神經網絡實戰&#xff1a;GRU 對比 LSTM 的中文情感分析&#xff08;三&#xff09;前言數據準備&#xff08;與 LSTM 相同&#xff09;模型搭建&#xff08;GRU&#xff09;…

學習游戲制作記錄(制作提示框以及使用鍵盤切換UI)8.21

1.制作裝備提示框創建提示框&#xff0c;添加文本子對象&#xff0c;用來描述名稱&#xff0c;類型以及屬性加成掛載垂直分配組件和文本大小適配組件&#xff0c;這樣圖像會根據文本大小來調整自己創建UI_ItemTip腳本并掛載在文本框上&#xff1a;[SerializeField] private Tex…

chapter07_初始化和銷毀方法

一、簡介 一個Bean&#xff0c;在進行實例化之后&#xff0c;需要進行兩種初始化 初始化屬性&#xff0c;由PropertyValues進行賦值初始化方法&#xff0c;由ApplicationContext統一調用&#xff0c;例如加載配置文件 Bean的初始化與銷毀&#xff0c;共有三種方式&#xff08;注…

open webui源碼分析6-Function

一、Functions簡介 可以把Tools作為依賴于外部服務的插件&#xff0c;Functions就是內部插件&#xff0c;二者都是用來增強open webui的能力的。Functions是輕量的&#xff0c;高度可定制的&#xff0c;并且是用純Python編寫的&#xff0c;所以你可以自由地創建任何東西——從新…

C2039 “unref“:不是“osgEarth::Symbology::Style”的成員 問題分析及解決方法

在osgEarth2.10中實現多線段連續測量功能時,遇到下圖中的錯誤; 經過測試和驗證,主要問題出現在下圖圈出代碼的定義上 圖22-1 對于22-1中的兩個變量這樣定義是錯誤的。因為Style類沒有繼承自osg::Referenced,因此不能與osg::ref_ptr配合使用

GitHub 熱榜項目 - 日榜(2025-08-19)

GitHub 熱榜項目 - 日榜(2025-08-19) 生成于&#xff1a;2025-08-19 統計摘要 共發現熱門項目&#xff1a;12 個 榜單類型&#xff1a;日榜 本期熱點趨勢總結 本期GitHub熱榜呈現三大技術熱點&#xff1a;1&#xff09;AI原生開發持續爆發&#xff0c;Archon OS、Parlant等…

ingress 配置ssl證書

模擬環境舉例&#xff1a; # 生成帶 OU 的證書配置文件 cat > csr.conf <<EOF [ req ] default_bits 2048 prompt no default_md sha256 distinguished_name dn[ dn ] C CN ST Beijing L Beijing O YourCompany, Inc. # 組織名稱 (必填) OU DevOps De…

Pandas 合并數據集:concat 和 append

文章目錄Pandas 合并數據集&#xff1a;concat 和 append回顧&#xff1a;NumPy 數組的拼接使用 pd.concat 進行簡單拼接重復索引將重復索引視為錯誤忽略索引添加多級索引&#xff08;MultiIndex&#xff09;鍵使用連接&#xff08;Join&#xff09;方式拼接append 方法Pandas …

2025年5月架構設計師綜合知識真題回顧,附參考答案、解析及所涉知識點(七)

本文主要回顧2025年上半年(2025-5-24)系統架構設計師考試上午綜合知識科目的選擇題,同時附帶參考答案、解析和所涉知識點。 2025年5月架構設計師綜合知識真題回顧,附參考答案、解析及所涉知識點(一) 2025年5月架構設計師綜合知識真題回顧,附參考答案、解析及所涉知識點(…

面向RF設計人員的微帶貼片天線計算器

微帶貼片天線和陣列可能是僅次于單極天線和偶極天線的最簡單的天線設計。這些天線也很容易集成到PCB中&#xff0c;因此通常用于5G天線陣列和雷達等高級系統。這些天線陣列在基諧模式和高階模式下也遵循一組簡單的設計方程&#xff0c;因此您甚至可以在不使用仿真工具的情況下設…

明基RD280U編程顯示器深度測評:碼農的「第二塊鍵盤」竟然會發光?

文章目錄前言一、開箱篇&#xff1a;當理工男遇到「俄羅斯套娃式包裝」二、外觀篇&#xff1a;深空灰的「代碼容器」1. 桌面變形記2. 保護肩頸的人體工學設計三、顯示篇&#xff1a;給代碼做「光子嫩膚」1. 28寸超大大屏 3:2屏比 4K超清2.專業編程模式&#xff0c;讓代碼一目…