鱼C论坛

 找回密码
 立即注册
查看: 952|回复: 7

多个文件夹excel数据合并问题

[复制链接]
发表于 2025-2-17 16:21:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
import os
import pandas as pd

def merge_excel_files_from_folders(root_folder):
   
    # 创建一个空的DataFrame来存储所有数据
    all_data = pd.DataFrame()
    # 遍历根文件夹中的所有子文件夹
    for foldername, subfolders, filenames in os.walk(root_folder):
        for filename in filenames:
            # 检查文件是否为Excel文件
            if filename.endswith('.xlsx') or filename.endswith('.xls'):
                # 构建文件的完整路径
                file_path = os.path.join(foldername, filename)
               
                # 读取Excel文件
                df = pd.read_excel(file_path)
               
                # 将读取的数据追加到all_data中
                all_data = pd.concat([all_data, df], ignore_index=True)

    return all_data

def save_merged_data_to_excel(data, output_file):
    # 将合并后的数据保存到新的Excel文件中
    data.to_excel(output_file, index=False)

if __name__ == "__main__":
    # 根文件夹路径,包含所有子文件夹和Excel文件
    root_folder = "E:/ai/shiyan"
   
    # 输出文件路径
    output_file = "E:/ai/shiyan/merged_data.xlsx"
   
    # 合并数据
    merged_data = merge_excel_files_from_folders(root_folder)
   
    # 保存合并后的数据到Excel文件
    save_merged_data_to_excel(merged_data, output_file)
   
    print(f"数据已成功合并并保存到 {output_file}")

这个程序只是将文件夹下的表格合在一张表上,怎么能够使结构相同的表格数据相加在一起。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-2-17 16:21:27 | 显示全部楼层
您可以调整代码,使其在合并各个Excel文件的数据时,以结构相同的表格数据进行相加。可以使用 groupbysum 方法来实现这一点。以下是修改后的代码:


  1. import os
  2. import pandas as pd

  3. def merge_excel_files_from_folders(root_folder):
  4.    
  5.     # 创建一个空的DataFrame来存储所有数据
  6.     all_data = pd.DataFrame()
  7.     # 遍历根文件夹中的所有子文件夹
  8.     for foldername, subfolders, filenames in os.walk(root_folder):
  9.         for filename in filenames:
  10.             # 检查文件是否为Excel文件
  11.             if filename.endswith('.xlsx') or filename.endswith('.xls'):
  12.                 # 构建文件的完整路径
  13.                 file_path = os.path.join(foldername, filename)
  14.                
  15.                 # 读取Excel文件
  16.                 df = pd.read_excel(file_path)
  17.                
  18.                 # 将读取的数据追加到all_data中
  19.                 all_data = pd.concat([all_data, df], ignore_index=True)

  20.     # 按相同结构的列进行分组并求和
  21.     merged_data = all_data.groupby(list(all_data.columns), as_index=False).sum()
  22.    
  23.     return merged_data

  24. def save_merged_data_to_excel(data, output_file):
  25.     # 将合并后的数据保存到新的Excel文件中
  26.     data.to_excel(output_file, index=False)

  27. if __name__ == "__main__":
  28.     # 根文件夹路径,包含所有子文件夹和Excel文件
  29.     root_folder = "E:/ai/shiyan"
  30.    
  31.     # 输出文件路径
  32.     output_file = "E:/ai/shiyan/merged_data.xlsx"
  33.    
  34.     # 合并数据
  35.     merged_data = merge_excel_files_from_folders(root_folder)
  36.    
  37.     # 保存合并后的数据到Excel文件
  38.     save_merged_data_to_excel(merged_data, output_file)
  39.    
  40.     print(f"数据已成功合并并保存到 {output_file}")
复制代码


以上代码通过 groupby 方法将相同结构的表格数据进行分组,并使用 sum 方法对这些分组数据进行求和。这样可以实现将多个Excel文件中的相同结构数据进行相加合并。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-2-17 19:25:19 | 显示全部楼层
表头有合并,行中有小标题,该怎么修改
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-2-17 19:25:31 | 显示全部楼层
wangpan10163 发表于 2025-02-17 19:25
表头有合并,行中有小标题,该怎么修改


对于表头存在合并单元格、行中有小标题的情况,可以先处理表头以将其标准化为扁平的单层结构(例如,通过合并多层表头为一层,或者删除无用的表头信息),然后,再处理数据中的小标题行,将其过滤或跳过。

下面是调整后的代码模板,假设您希望跳过带有小标题的行,并且将合并单元格的表头扁平化:

  1. import os
  2. import pandas as pd

  3. def process_excel_file(file_path):
  4.     # 读取Excel文件,并指定header=None以逐行读取
  5.     df = pd.read_excel(file_path, header=None)
  6.    
  7.     # 假定第一行为表头(处理合并单元格)
  8.     df.columns = df.iloc[0]  # 使用第一行作为列名
  9.     df = df[1:]  # 删除第一行(已作为表头)
  10.    
  11.     # 处理小标题行,例如,假设小标题行中某一列值为特定的标志
  12.     df = df[~df.iloc[:, 0].str.contains('小标题', na=False)]  # 根据具体规则过滤掉小标题行
  13.    
  14.     return df

  15. def merge_excel_files_from_folders(root_folder):
  16.     all_data = pd.DataFrame()
  17.    
  18.     for foldername, subfolders, filenames in os.walk(root_folder):
  19.         for filename in filenames:
  20.             if filename.endswith('.xlsx') or filename.endswith('.xls'):
  21.                 file_path = os.path.join(foldername, filename)
  22.                
  23.                 # 处理单个文件并标准化数据
  24.                 df = process_excel_file(file_path)
  25.                
  26.                 # 合并数据
  27.                 all_data = pd.concat([all_data, df], ignore_index=True)

  28.     return all_data

  29. def save_merged_data_to_excel(data, output_file):
  30.     data.to_excel(output_file, index=False)

  31. if __name__ == "__main__":
  32.     root_folder = "E:/ai/shiyan"
  33.     output_file = "E:/ai/shiyan/merged_data.xlsx"
  34.    
  35.     merged_data = merge_excel_files_from_folders(root_folder)
  36.     save_merged_data_to_excel(merged_data, output_file)
  37.    
  38.     print(f"数据已成功合并并保存到 {output_file}")
复制代码


### 关键修改点:
1. **处理合并单元格的表头**:使用 header=None 读取表格的所有内容后,将第一行的数据设置为列名。
2. **移除小标题行**:通过条件判断(如 str.contains('小标题'))来过滤掉不需要的小标题行。
3. **确保数据一致性**:在处理过程中保证每个文件生成标准化的结构。

你需要根据具体的表格特点调整 process_excel_file 函数中的逻辑,比如表头的位置和小标题的判定规则。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-2-17 23:26:57 | 显示全部楼层
如果需要将第一列忽略,以小标题的其中1列作为表头呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-2-17 23:29:43 | 显示全部楼层
wangpan10163 发表于 2025-02-17 23:26
如果需要将第一列忽略,以小标题的其中1列作为表头呢


好的,如果需要忽略第一列,并将小标题的某一列作为表头,可以参考下面的代码进行调整。以下代码假设小标题行中某一列具有特定的标志,用于识别和设置表头:

  1. import os
  2. import pandas as pd

  3. def process_excel_file(file_path):
  4.     # 读取Excel文件,并指定header=None以逐行读取
  5.     df = pd.read_excel(file_path, header=None)
  6.    
  7.     # 忽略第一列
  8.     df = df.iloc[:, 1:]
  9.    
  10.     # 找到小标题行,假设小标题具有特定标志(例如,该行的某一列包含特定值)
  11.     header_row_index = df[df.iloc[:, 0].str.contains('小标题标志', na=False)].index[0]
  12.    
  13.     # 设定该行为新的表头,并重新读取数据
  14.     df.columns = df.iloc[header_row_index]
  15.     df = df[header_row_index + 1:]  # 删除小标题行及其之前的行
  16.    
  17.     # 重置索引
  18.     df.reset_index(drop=True, inplace=True)
  19.    
  20.     return df

  21. def merge_excel_files_from_folders(root_folder):
  22.     all_data = pd.DataFrame()
  23.    
  24.     for foldername, subfolders, filenames in os.walk(root_folder):
  25.         for filename in filenames:
  26.             if filename.endswith('.xlsx') or filename.endswith('.xls'):
  27.                 file_path = os.path.join(foldername, filename)
  28.                
  29.                 # 处理单个文件并标准化数据
  30.                 df = process_excel_file(file_path)
  31.                
  32.                 # 合并数据
  33.                 all_data = pd.concat([all_data, df], ignore_index=True)

  34.     return all_data

  35. def save_merged_data_to_excel(data, output_file):
  36.     data.to_excel(output_file, index=False)

  37. if __name__ == "__main__":
  38.     root_folder = "E:/ai/shiyan"
  39.     output_file = "E:/ai/shiyan/merged_data.xlsx"
  40.    
  41.     merged_data = merge_excel_files_from_folders(root_folder)
  42.     save_merged_data_to_excel(merged_data, output_file)
  43.    
  44.     print(f"数据已成功合并并保存到 {output_file}")
复制代码


### 关键修改点:
1. **忽略第一列**:使用 df = df.iloc[:, 1:] 来忽略第一列。
2. **找到并设置新的表头**:通过指定标志(如小标题标志)找到小标题行的索引,并将此行设为新的表头。
3. **删除小标题行及其之前的行**:根据计算出的索引范围删除这些行。
4. **重置索引**:使用 df.reset_index(drop=True, inplace=True) 重新设置DataFrame的索引。

请根据具体的小标题标志来调整识别条件和处理逻辑。这段代码将帮助您根据需求合并多个Excel文件的数据。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 15:02 | 显示全部楼层
FishC 发表于 2025-2-17 23:29
好的,如果需要忽略第一列,并将小标题的某一列作为表头,可以参考下面的代码进行调整。以下代码假设小 ...

能不能在程序开始前让用户录入需要排除的行号(如1、2、3、4、5)和列号(如A   B  C)?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 15:04 | 显示全部楼层
凊风 发表于 2025-10-21 15:02
FishC 发表于 2025-2-17 23:29
好的,如果需要忽略第 ...


当然可以!我们可以让用户在程序开始时输入要排除的行号和列号。以下是修改后的代码:

  1. import os
  2. import pandas as pd
  3. import re

  4. def get_user_input():
  5.     print("请输入要排除的行号(用逗号分隔,例如:1,2,3,4,5):")
  6.     skip_rows_input = input().strip()
  7.     skip_rows = [int(x.strip()) - 1 for x in skip_rows_input.split(',') if x.strip()]
  8.    
  9.     print("请输入要排除的列号(用逗号分隔,例如:A,B,C):")
  10.     skip_cols_input = input().strip()
  11.     skip_cols = []
  12.    
  13.     for col in skip_cols_input.split(','):
  14.         col = col.strip().upper()
  15.         if col:
  16.             # 将列字母转换为数字索引(A=0, B=1, ...)
  17.             col_idx = 0
  18.             for i, char in enumerate(col[::-1]):
  19.                 col_idx += (ord(char) - 64) * (26 ** i)
  20.             skip_cols.append(col_idx - 1)
  21.    
  22.     return skip_rows, skip_cols

  23. def process_excel_file(file_path, skip_rows, skip_cols):
  24.     # 读取Excel文件
  25.     df = pd.read_excel(file_path, header=None)
  26.    
  27.     # 排除指定的行
  28.     if skip_rows:
  29.         df = df.drop(skip_rows)
  30.    
  31.     # 排除指定的列
  32.     if skip_cols:
  33.         df = df.drop(columns=skip_cols)
  34.    
  35.     # 重置索引
  36.     df.reset_index(drop=True, inplace=True)
  37.    
  38.     # 将第一行作为表头
  39.     df.columns = df.iloc[0]
  40.     df = df[1:]
  41.     df.reset_index(drop=True, inplace=True)
  42.    
  43.     return df

  44. def merge_excel_files_from_folders(root_folder, skip_rows, skip_cols):
  45.     all_data = pd.DataFrame()
  46.    
  47.     for foldername, subfolders, filenames in os.walk(root_folder):
  48.         for filename in filenames:
  49.             if filename.endswith('.xlsx') or filename.endswith('.xls'):
  50.                 file_path = os.path.join(foldername, filename)
  51.                
  52.                 # 处理单个文件
  53.                 df = process_excel_file(file_path, skip_rows, skip_cols)
  54.                
  55.                 # 合并数据
  56.                 all_data = pd.concat([all_data, df], ignore_index=True)
  57.    
  58.     return all_data

  59. def save_merged_data_to_excel(data, output_file):
  60.     data.to_excel(output_file, index=False)

  61. if __name__ == "__main__":
  62.     # 获取用户输入
  63.     skip_rows, skip_cols = get_user_input()
  64.    
  65.     # 根文件夹路径
  66.     root_folder = "E:/ai/shiyan"
  67.    
  68.     # 输出文件路径
  69.     output_file = "E:/ai/shiyan/merged_data.xlsx"
  70.    
  71.     # 合并数据
  72.     merged_data = merge_excel_files_from_folders(root_folder, skip_rows, skip_cols)
  73.    
  74.     # 保存合并后的数据
  75.     save_merged_data_to_excel(merged_data, output_file)
  76.    
  77.     print(f"数据已成功合并并保存到 {output_file}")
复制代码


这个修改后的代码具有以下特点:

1. 添加了 get_user_input() 函数,用于获取用户输入的要排除的行号和列号
2. 行号从1开始计数(符合Excel的习惯),程序内部会自动转换为从0开始的索引
3. 列号支持字母表示(A, B, C等),程序会自动转换为数字索引
4. 处理Excel文件时会跳过指定的行和列
5. 将处理后的数据的第一行作为表头

使用示例:
- 当程序提示输入行号时,输入:1,2,3,4,5
- 当程序提示输入列号时,输入:A,B,C

这样程序就会排除第1-5行和A、B、C列,然后将剩余数据的第一行作为表头进行合并。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-10-22 04:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表