如何基于多份制表符分隔文件生成水果频率统计表格并导出
解决多文件水果频率统计与导出问题
首先先帮你修正原代码里的一个小bug:循环读取文件内容时,你写的是for line in file,但这里的file是文件路径字符串,应该改成for line in input(也就是你打开的文件对象),不然会遍历路径的字符而非文件的行,直接导致错误。
接下来针对你的需求,我给你两种实用的实现方案,包括你提到的numpy相关思路,以及更简便的高效方案:
方案一:用Pandas快速处理(推荐)
Pandas天生适合处理这种表格型的聚合与导出需求,代码简洁且易维护,能自动帮你处理「某水果在某文件中不存在」的场景:
import glob import os import pandas as pd input_directory = "./your_input_dir/" # 替换成你的实际路径 file_list = glob.glob(input_directory + "*.txt") # 收集所有文件的数据,添加文件名作为标识列 dfs = [] for file_path in file_list: shortname = os.path.basename(file_path) # 读取tab分隔文件,指定列名与数据类型 df = pd.read_csv(file_path, sep="\t", names=["fruit", "frequency"], dtype={"frequency": int}) df["filename"] = shortname dfs.append(df) # 合并所有数据到一个DataFrame combined_df = pd.concat(dfs, ignore_index=True) # 转成透视表:行是水果名,列是文件名,值为频率,缺失项填充为0 pivot_df = combined_df.pivot_table( index="fruit", columns="filename", values="frequency", fill_value=0, aggfunc="sum" # 若同一文件内有重复水果,自动求和 ) # 导出为tab分隔的结果文件 pivot_df.to_csv("fruit_frequency_summary.txt", sep="\t")
方案二:纯Python实现(无需第三方库)
如果你不想依赖pandas,也可以用纯Python完成,核心是先收集所有水果和文件名的全集,再逐个组合检查频率:
import glob import os from collections import defaultdict input_directory = "./your_input_dir/" file_list = glob.glob(input_directory + "*.txt") # 用嵌套字典存储数据:master_dict[水果名][文件名] = 频率 master_dict = defaultdict(dict) all_filenames = [] for file_path in file_list: shortname = os.path.basename(file_path) all_filenames.append(shortname) with open(file_path, "r") as f: for line in f: line = line.strip() if not line: continue fruit, frequency = line.split("\t") master_dict[fruit][shortname] = int(frequency) # 获取所有水果的集合 all_fruits = list(master_dict.keys()) # 生成输出内容(含表头) output_lines = ["fruit\t" + "\t".join(all_filenames)] for fruit in all_fruits: freq_values = [] for filename in all_filenames: # 检查该水果在当前文件是否存在,不存在则填0 freq_values.append(str(master_dict[fruit].get(filename, 0))) output_lines.append(fruit + "\t" + "\t".join(freq_values)) # 写入结果文件 with open("fruit_frequency_summary.txt", "w") as f: f.write("\n".join(output_lines))
关于Numpy的实现思路
Numpy确实可以用来存储这类数据,但它更擅长处理纯数值型数组,对于带字符串标签(水果名、文件名)的表格,需要额外做索引映射:
- 将所有水果名映射为整数索引(比如
fruit_to_idx = {fruit: i for i, fruit in enumerate(all_fruits)}) - 将所有文件名映射为整数索引(
file_to_idx = {name: i for i, name in enumerate(all_filenames)}) - 创建一个全0的numpy数组,形状为
(len(all_fruits), len(all_filenames)) - 遍历收集到的频率数据,给对应索引位置赋值
- 最后将数组与标签组合,导出为tab分隔文件
不过这种方法比前两种方案繁琐很多,除非你需要后续对数值做大量numpy运算,否则不太推荐。
内容的提问来源于stack exchange,提问作者superasiantomtom95
相关产品推荐
相关产品推荐

