news 2026/9/2 10:45:22

零基础Python数据分析实战:从环境搭建到NumPy/Pandas项目应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
零基础Python数据分析实战:从环境搭建到NumPy/Pandas项目应用

在实际数据分析工作中,很多初学者会陷入一个误区:认为只要学会了Python语法,就能立刻上手处理数据。但现实是,从零基础到能独立完成一个数据分析项目,中间横亘着环境配置、库安装、语法理解、数据处理库应用以及排错能力等多道关卡。本文旨在为真正的零基础读者提供一条清晰、可执行的学习路径,覆盖从Python环境搭建、基础语法(包括while循环),到核心数据分析库NumPy和Pandas的实战应用。我们将通过一个连贯的“销售数据分析”小项目,将分散的知识点串联起来,让你不仅能看懂代码,更能理解每一步背后的逻辑,并具备独立排查常见错误的能力。

1. 理解数据分析的技术栈:Python、NumPy与Pandas的角色

在开始动手之前,必须先理清这几个核心组件之间的关系,否则很容易在后续的学习中混淆概念,遇到问题不知从何查起。

1.1 Python:数据分析的“操作系统”

Python本身是一门编程语言,它提供了基础的语法规则(如变量、循环、函数)和标准库。你可以把它看作一个“操作系统”,它提供了运行其他软件(库)的基础环境。数据分析中,我们主要利用Python的语法来组织逻辑、控制流程,并调用更专业的工具(库)来完成具体任务。

1.2 NumPy:高性能数值计算的“发动机”

NumPy(Numerical Python)是Python科学计算的基础包。它的核心是ndarray(N维数组)对象,这是一个快速、灵活的大数据容器。与Python原生的列表(list)相比,NumPy数组在存储和操作数值数据时效率高出几个数量级。

  • 为什么需要NumPy?Python的列表可以存放不同类型的数据,灵活性高但效率低。NumPy数组要求元素类型相同,并且数据在内存中连续存储,这使得它能利用现代CPU的向量化指令进行批量运算,速度极快。几乎所有其他科学计算和数据分析库(包括Pandas)都构建在NumPy之上。
  • 核心功能:创建数组、数组索引与切片、数组形状操作、通用函数(ufunc)、线性代数运算、随机数生成等。

1.3 Pandas:数据处理与分析的“瑞士军刀”

Pandas是基于NumPy构建的,提供了更高级的数据结构和数据分析工具。如果说NumPy擅长处理同质的数值数组,那么Pandas则专为处理表格型异质型数据而设计。

  • 核心数据结构
    • Series:带标签的一维数组,可以看作Excel中的一列。
    • DataFrame:带标签的二维表格型数据结构,是Pandas中最常用、最重要的对象,可以看作一个Excel工作表或SQL表。
  • 核心功能:数据读取与写入(CSV、Excel、SQL等)、数据清洗(处理缺失值、重复值)、数据转换(筛选、排序、分组、聚合、合并)、数据可视化基础集成等。

三者关系总结:Python是环境,NumPy提供底层的高性能数组计算能力,Pandas在NumPy的基础上,提供了更贴近业务分析(如Excel操作)的友好接口。一个典型的数据分析流程是:用Pandas读入和清洗数据,在需要复杂数值计算时调用NumPy,最后再用Pandas或可视化库(如Matplotlib)呈现结果。

2. 环境准备:安装Python与核心库并验证

一个稳定、独立的环境是学习的起点。强烈建议使用Anaconda或Miniconda进行环境管理,它可以避免不同项目间的库版本冲突。

2.1 安装Python与包管理工具

对于Windows/macOS用户,最省心的方式是安装Miniconda(一个更轻量级的Anaconda)。

  1. 下载Miniconda:访问Miniconda官网,根据你的操作系统(Windows/macOS/Linux)和系统架构(64位)下载对应的Python 3.x版本安装包。
  2. 安装:Windows用户运行.exe安装程序,一路“Next”,注意在“Advanced Options”中勾选“Add Miniconda3 to my PATH environment variable”(将Miniconda加入系统PATH),这样可以在任意命令行中使用。macOS/Linux用户运行下载的脚本即可。
  3. 验证安装:打开终端(Windows:Anaconda Prompt或CMD;macOS/Linux:Terminal),输入以下命令,应显示已安装的conda版本。
    conda --version

2.2 创建专属的虚拟环境

为数据分析项目创建一个独立环境是个好习惯。

# 创建一个名为`data_analysis`的虚拟环境,并指定Python版本为3.9(一个稳定版本) conda create -n data_analysis python=3.9 # 激活该环境 conda activate data_analysis

激活后,命令行的提示符前通常会显示环境名(data_analysis)

2.3 安装NumPy、Pandas及Jupyter Notebook

在激活的data_analysis环境中,使用condapip安装。conda在解决依赖关系方面通常更优。

# 使用conda安装(推荐) conda install numpy pandas jupyter # 或者使用pip安装 # pip install numpy pandas jupyter

jupyter notebook是一个交互式编程环境,非常适合数据分析和探索,可以边写代码边看结果。

2.4 验证安装与排查经典错误

安装后,必须验证库是否能正常导入,并理解常见的版本冲突错误。

验证步骤:

  1. 在终端输入jupyter notebook启动Jupyter。
  2. 在打开的网页中新建一个Python笔记本(Notebook)。
  3. 在第一个单元格中输入并运行以下代码:
    import numpy as np import pandas as pd print(f"NumPy版本: {np.__version__}") print(f"Pandas版本: {pd.__version__}") print("NumPy和Pandas导入成功!")
    如果成功输出版本号,则环境配置正确。

常见安装错误排查:在安装过程中,你可能会遇到搜索材料中提到的类似错误。以下是原因和解决方案:

错误现象可能原因解决方案
AttributeError: module 'numpy' has no attribute 'arange'通常是因为文件命名冲突,例如你将自己的脚本命名为numpy.py,导致Python优先导入了你这个空文件,而不是真正的NumPy库。永远不要numpy.py,pandas.py,math.py等标准库或第三方库的名字命名你的Python文件。检查并重命名冲突的文件。
ERROR: Could not find a version that satisfies the requirement pandas或网络超时网络问题,或pip源不可用。更换为国内镜像源加速下载,例如使用清华源:pip install numpy pandas -i https://pypi.tuna.tsinghua.edu.cn/simple
RuntimeError: NumPy was built with baseline optimizations...NumPy版本与你的CPU指令集不兼容。这通常发生在从源码编译或使用某些特定版本时。最简单的办法是使用conda install numpy让conda自动选择与你平台兼容的预编译版本。或者使用pip安装官方发布的二进制轮子(wheel)。
iopaint安装 gradio 4.21.0 requires numpy~=1.0, but you have numpy 2.2.6 which is incompatible.库之间的版本依赖冲突。一个新库要求旧版NumPy,但你已安装了新版。这是包管理中的常见问题。在虚拟环境中,可以为这个特定项目安装兼容的版本组合:conda install numpy=1.23.5 pandas。使用conda通常比pip更能妥善解决此类依赖问题。

注意:虚拟环境是隔离的,在data_analysis环境中安装的包,不会影响系统或其他环境。每次打开新的终端进行数据分析前,都需要先执行conda activate data_analysis来激活这个环境。

3. Python基础语法精要:聚焦数据分析场景

我们不会面面俱到地讲Python语法,而是聚焦于数据分析中最常用、最容易出错的部分。假设你已了解变量、数据类型(整型、浮点、字符串、布尔)、列表、字典等基本概念。

3.1 条件判断与循环:while循环的陷阱

for循环通常用于遍历一个已知的序列(如列表、数组的每一行)。而while循环则在条件为真时重复执行代码块,常用于读取流数据或达到某个条件前持续计算。

基本语法:

count = 0 while count < 5: # 当count小于5时,执行循环体内的代码 print(f"当前计数: {count}") count += 1 # 千万别忘了改变条件变量,否则会陷入无限循环! print("循环结束")

输出:

当前计数: 0 当前计数: 1 当前计数: 2 当前计数: 3 当前计数: 4 循环结束

数据分析中的典型应用与坑:

  • 应用场景:模拟迭代计算直到收敛(如梯度下降)、从API或文件中持续读取数据直到特定标记出现。
  • 常见坑1:无限循环。忘记在循环体内更新条件判断变量,导致循环永不停止。在Jupyter中,如果代码块前的In [*]中的*一直闪烁,很可能就是无限循环,可以尝试中断内核(Kernel -> Interrupt)。
  • 常见坑2:breakcontinue使用不当break直接跳出整个循环,continue跳过当前轮次剩余代码进入下一轮。在复杂逻辑中滥用会导致流程难以理解。
    # 一个结合break的示例:查找列表中第一个大于10的数 numbers = [1, 5, 12, 3, 8, 15] index = 0 found = None while index < len(numbers): if numbers[index] > 10: found = numbers[index] break # 找到后立即退出循环,提高效率 index += 1 print(f"找到的第一个大于10的数是: {found}")

3.2 函数:封装数据处理逻辑

函数是将一段可重用的代码块组织在一起的方式。在数据分析中,我们经常将数据清洗、转换的步骤写成函数。

定义与调用:

def calculate_statistics(data_list): """计算一个数值列表的平均值和总和。 参数: data_list (list): 一个包含数值的列表。 返回: tuple: 包含(平均值, 总和)的元组。 """ if not data_list: # 处理空列表的边界情况 return 0, 0 total = sum(data_list) average = total / len(data_list) return average, total # 可以返回多个值 # 调用函数 sales = [200, 350, 420, 190, 300] avg_sales, total_sales = calculate_statistics(sales) print(f"平均销售额: {avg_sales:.2f}, 总销售额: {total_sales}")

关键点:

  1. 文档字符串"""..."""中的内容用于解释函数用途,是好习惯。
  2. 参数与返回值:函数可以接收输入(参数),并返回输出。返回多个值时,实际是返回一个元组(tuple)。
  3. 边界处理:函数内对异常情况(如空列表)进行处理,使函数更健壮。

4. NumPy实战:高效处理数值数组

现在进入核心环节。我们将通过创建、操作数组来感受NumPy的高效。

4.1 创建NumPy数组

首先导入NumPy,惯例是import numpy as np

import numpy as np # 从Python列表创建 arr1 = np.array([1, 2, 3, 4, 5]) print(f"一维数组: {arr1}, 类型: {arr1.dtype}") # 创建二维数组(矩阵) arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print(f"二维数组:\n{arr2d}") print(f"形状: {arr2d.shape}") # 输出 (3, 3), 3行3列 # 使用内置函数快速创建 zeros_arr = np.zeros((2, 4)) # 2行4列的全0数组 ones_arr = np.ones((3, 3)) # 3x3的全1数组 range_arr = np.arange(0, 10, 2) # 类似range,生成[0, 2, 4, 6, 8] random_arr = np.random.rand(3, 2) # 3行2列的[0,1)区间随机数数组

4.2 数组索引、切片与形状操作

这是NumPy最强大的特性之一,语法与Python列表类似,但支持多维。

arr = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]]) # 索引:获取单个元素 print(arr[0, 1]) # 输出 20 (第0行,第1列) # 切片:获取子数组 print(arr[1:, :2]) # 输出 [[40 50] # [70 80]] # 解释:`1:` 表示从第1行到最后一行,`:2`表示从第0列到第2列(不包括第2列) # 形状操作 flattened = arr.flatten() # 展平为一维数组 [10 20 30 40 50 60 70 80 90] reshaped = arr.reshape(1, 9) # 重塑为1行9列的二维数组 [[10 20 30 40 50 60 70 80 90]] # 注意:reshape后的总元素数必须与原数组一致 (3*3 = 1*9)

4.3 向量化运算与通用函数

这是NumPy速度远超Python循环的关键。运算直接作用于整个数组,而不是单个元素。

a = np.array([1, 2, 3, 4]) b = np.array([5, 6, 7, 8]) # 向量化运算 print(a + b) # 对应元素相加 [ 6 8 10 12] print(a * 2) # 每个元素乘以2 [2 4 6 8] print(a > 2) # 布尔运算 [False False True True] # 通用函数 (ufunc) print(np.sqrt(a)) # 开方 [1. 1.41421356 1.73205081 2. ] print(np.mean(a)) # 平均值 2.5 print(np.sum(a)) # 总和 10 print(np.std(a)) # 标准差 1.118033988749895

5. Pandas实战:表格数据操作核心

Pandas的DataFrame是数据分析的绝对核心。我们通过一个模拟的销售数据集来学习。

5.1 创建与查看DataFrame

import pandas as pd # 从字典创建DataFrame,键是列名,值是数据列表 data = { '日期': ['2023-10-01', '2023-10-01', '2023-10-02', '2023-10-02', '2023-10-03'], '产品': ['A', 'B', 'A', 'C', 'B'], '销售额': [200, 350, 220, 120, 400], '数量': [5, 7, 6, 3, 10] } df = pd.DataFrame(data) print("原始数据:") print(df) print("\nDataFrame信息:") print(df.info()) # 查看列类型、非空值数量 print("\n描述性统计:") print(df.describe()) # 对数值列进行统计(计数、均值、标准差、分位数等)

5.2 数据选取与过滤

# 选择单列,返回一个Series sales_series = df['销售额'] print(sales_series) # 选择多列,返回一个DataFrame subset = df[['日期', '产品']] print(subset) # 使用loc基于标签选择(行索引和列名) print(df.loc[0]) # 选择第一行所有列 print(df.loc[1:3, ['产品', '销售额']]) # 选择第2到4行(包含4),指定列 # 使用iloc基于整数位置选择 print(df.iloc[0]) # 第一行 print(df.iloc[1:4, 0:2]) # 第2到4行(不包含4),第0到2列(不包含2) # 布尔索引:强大的过滤功能 high_sales = df[df['销售额'] > 250] # 筛选销售额大于250的行 print("高销售额记录:") print(high_sales) product_a_sales = df[df['产品'] == 'A'] # 筛选产品为A的行 print("产品A的记录:") print(product_a_sales)

5.3 数据清洗:处理缺失值与重复值

真实数据很少是干净的。Pandas提供了丰富的清洗工具。

# 假设我们有一个带缺失值(NaN)和重复行的数据 df_dirty = pd.DataFrame({ 'A': [1, 2, None, 4, 2], 'B': [5, None, None, 8, 5], 'C': ['x', 'y', 'z', 'x', 'y'] }) print("脏数据:") print(df_dirty) # 检查缺失值 print("\n缺失值统计:") print(df_dirty.isnull().sum()) # 处理缺失值 # 1. 删除包含缺失值的行 df_dropna = df_dirty.dropna() print("\n删除缺失值后:") print(df_dropna) # 2. 填充缺失值 df_fillna = df_dirty.fillna({'A': df_dirty['A'].mean(), 'B': 0}) # A列用均值填充,B列用0填充 print("\n填充缺失值后:") print(df_fillna) # 处理重复值 print("\n重复行:") print(df_dirty[df_dirty.duplicated()]) # 标识重复行 df_nodup = df_dirty.drop_duplicates() # 删除重复行 print("\n删除重复行后:") print(df_nodup)

5.4 数据分组与聚合

这是数据分析中最常见的操作之一,用于回答诸如“每个产品的总销售额是多少?”之类的问题。

# 按‘产品’分组,并计算每组的‘销售额’总和和‘数量’平均值 grouped = df.groupby('产品').agg({ '销售额': 'sum', '数量': 'mean' }).reset_index() # reset_index()将分组键‘产品’从索引变回普通列 print("按产品聚合的结果:") print(grouped) # 输出: # 产品 销售额 数量 # 0 A 420 5.5 # 1 B 750 8.5 # 2 C 120 3.0

5.5 数据合并

数据常常来自多个源,需要合并。

# 创建另一个包含产品价格的DataFrame df_price = pd.DataFrame({ '产品': ['A', 'B', 'C'], '单价': [40, 50, 40] }) print("价格表:") print(df_price) # 使用merge将销售数据与价格数据合并(类似SQL JOIN) df_merged = pd.merge(df, df_price, on='产品', how='left') # 左连接,以df为主 print("\n合并后的数据:") print(df_merged) # 可以计算每笔交易的金额(销售额应等于数量*单价,这里用于验证或计算新列) df_merged['计算销售额'] = df_merged['数量'] * df_merged['单价'] print("\n添加计算列后:") print(df_merged[['日期', '产品', '数量', '单价', '销售额', '计算销售额']])

6. 综合项目:销售数据分析小报告

现在,我们将前面所有知识点串联起来,完成一个简单的端到端数据分析流程。

项目目标:分析一份销售数据,计算关键指标,并找出潜在问题。

步骤 1:模拟数据并加载

import numpy as np import pandas as pd # 生成模拟数据 np.random.seed(42) # 确保每次运行生成相同的数据 dates = pd.date_range(start='2023-10-01', periods=30, freq='D') products = ['产品A', '产品B', '产品C'] data = { '日期': np.random.choice(dates, 100), '产品': np.random.choice(products, 100), '销售数量': np.random.randint(1, 20, 100), '单价': np.random.choice([10.0, 20.0, 30.0], 100) } df_sales = pd.DataFrame(data) # 计算销售额 df_sales['销售额'] = df_sales['销售数量'] * df_sales['单价'] # 故意插入一些缺失值和重复行 df_sales.loc[10:12, '单价'] = np.nan df_sales = pd.concat([df_sales, df_sales.head(3)]) # 复制前3行作为重复数据 df_sales = df_sales.sample(frac=1).reset_index(drop=True) # 打乱顺序 print("原始模拟数据 (前10行):") print(df_sales.head(10)) print(f"\n数据形状: {df_sales.shape}")

步骤 2:数据清洗

# 1. 处理缺失值:单价缺失用该产品的平均单价填充 product_avg_price = df_sales.groupby('产品')['单价'].transform('mean') df_sales['单价'] = df_sales['单价'].fillna(product_avg_price) # 重新计算填充后的销售额 df_sales['销售额'] = df_sales['销售数量'] * df_sales['单价'] # 2. 处理重复值 initial_count = len(df_sales) df_sales = df_sales.drop_duplicates() final_count = len(df_sales) print(f"删除了 {initial_count - final_count} 条重复记录。") # 3. 检查清洗后数据 print("\n清洗后数据信息:") print(df_sales.info())

步骤 3:数据分析与计算指标

# 1. 总体指标 total_sales = df_sales['销售额'].sum() total_quantity = df_sales['销售数量'].sum() avg_unit_price = df_sales['单价'].mean() print(f"总销售额: {total_sales:.2f}") print(f"总销售数量: {total_quantity}") print(f"平均单价: {avg_unit_price:.2f}") # 2. 按产品分析 product_summary = df_sales.groupby('产品').agg( 总销售额=('销售额', 'sum'), 总数量=('销售数量', 'sum'), 平均单价=('单价', 'mean'), 订单数=('日期', 'count') ).reset_index() print("\n按产品汇总:") print(product_summary) # 3. 按日期分析(每日销售额) daily_sales = df_sales.groupby('日期')['销售额'].sum().reset_index() print("\n每日销售额 (前5天):") print(daily_sales.head())

步骤 4:简单可视化与洞察虽然本文聚焦数据处理,但可视化是分析的最后一环。我们使用Pandas内置的绘图功能(基于Matplotlib)快速查看。

import matplotlib.pyplot as plt # 设置中文字体(如果需要)和图形大小 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 # 绘制产品总销售额柱状图 product_summary.plot(kind='bar', x='产品', y='总销售额', legend=False) plt.title('各产品总销售额对比') plt.ylabel('销售额') plt.tight_layout() plt.show() # 绘制每日销售额趋势图 daily_sales.plot(kind='line', x='日期', y='销售额', legend=False) plt.title('每日销售额趋势') plt.ylabel('销售额') plt.tight_layout() plt.show()

通过图表,可以直观看出哪个产品贡献最大,以及销售额随时间的变化趋势。

7. 生产环境与学习环境的差异及最佳实践

在个人电脑上跑通代码只是第一步。要将这些技能应用于实际工作或更复杂的项目,还需要注意以下方面。

7.1 数据读取与存储

学习时我们用字典创建数据,实际项目数据通常来自文件或数据库。

# 从CSV文件读取(最常用) # df = pd.read_csv('sales_data.csv', encoding='utf-8') # 指定编码 # df = pd.read_csv('sales_data.csv', parse_dates=['日期']) # 自动解析日期列 # 从Excel文件读取 # df = pd.read_excel('sales_data.xlsx', sheet_name='Sheet1') # 写入到CSV文件 # df.to_csv('cleaned_sales_data.csv', index=False) # index=False避免将行索引写入文件 # 写入到Excel文件 # df.to_excel('report.xlsx', sheet_name='Summary', index=False)

最佳实践

  • 使用encoding参数处理中文等非ASCII字符。
  • 使用parse_dates参数将字符串列自动转换为日期时间类型。
  • 保存数据时,通常不需要保存行索引(index=False)。

7.2 处理大数据集

当数据量很大(超过内存)时,Pandas默认的读取方式会失败。

  • 分块读取:使用chunksize参数。
    chunk_iter = pd.read_csv('huge_file.csv', chunksize=100000) for chunk in chunk_iter: # 处理每个块,例如过滤、聚合 process(chunk)
  • 使用更高效的数据类型:Pandas默认用int64float64存储数字,如果数值范围小,可以向下转换以节省内存。
    df['销售数量'] = df['销售数量'].astype('int32') df['单价'] = df['单价'].astype('float32')
  • 考虑其他工具:对于超大规模数据,可能需要使用Dask、PySpark或直接使用数据库(如SQL)进行预处理。

7.3 代码健壮性与可维护性

  • 异常处理:文件可能不存在,数据可能格式错误。
    import os file_path = 'data.csv' try: if os.path.exists(file_path): df = pd.read_csv(file_path) else: raise FileNotFoundError(f"文件 {file_path} 不存在") except pd.errors.EmptyDataError: print("文件为空。") except Exception as e: print(f"读取文件时发生错误: {e}")
  • 函数化与模块化:将数据清洗、分析、可视化的步骤封装成函数,并放在不同的Python模块(.py文件)中,通过主程序调用。这使代码易于测试和复用。
  • 使用配置文件:将数据库连接字符串、文件路径、关键参数等写入配置文件(如config.yamlconfig.ini),避免硬编码在代码中。

7.4 版本控制与依赖管理

  • 使用Git:代码必须用Git管理。初始化仓库,频繁提交,写清晰的提交信息。
  • 记录环境依赖:使用pip freeze > requirements.txtconda env export > environment.yml命令将当前环境的包列表导出。他人可以通过pip install -r requirements.txtconda env create -f environment.yml复现完全相同的环境。

从安装Python、理解while循环等基础语法,到掌握NumPy数组运算和Pandas表格操作,这条路径的核心在于实践。不要试图一次性记住所有API,而是掌握核心概念(如向量化、DataFrame、分组聚合)和常见操作(索引、过滤、合并)。遇到问题时,善用官方文档和搜索引擎(准确描述错误信息)。接下来,可以尝试寻找真实数据集(如Kaggle、公开政府数据)重复上述清洗、分析、可视化的流程,这是巩固技能的最佳方式。当熟悉了单机数据处理后,可以进一步学习使用SQL进行数据查询,以及利用matplotlibseaborn库制作更精美的图表,从而构建起完整的数据分析能力栈。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 10:43:26

RVC变声器完整教程:10分钟语音数据,三步练出你的AI音色

RVC变声器完整教程&#xff1a;10分钟语音数据&#xff0c;三步练出你的AI音色 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-V…

作者头像 李华
网站建设 2026/9/2 10:43:24

免费把微信聊天记录导出成文档:WeChatMsg 完整上手指南

免费把微信聊天记录导出成文档&#xff1a;WeChatMsg 完整上手指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeCh…

作者头像 李华
网站建设 2026/9/2 10:43:15

一条命令导出微信聊天记录:WeChatMsg 从导出到年度报告

一条命令导出微信聊天记录&#xff1a;WeChatMsg 从导出到年度报告 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeCh…

作者头像 李华
网站建设 2026/9/2 10:43:11

OCRmyPDF:让扫描PDF秒变可搜索文本的终极指南

OCRmyPDF&#xff1a;让扫描PDF秒变可搜索文本的终极指南 【免费下载链接】OCRmyPDF OCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched 项目地址: https://gitcode.com/GitHub_Trending/oc/OCRmyPDF 一份 200 页的扫描合同没有文本…

作者头像 李华