You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas DataFrame行更新(+=操作)实现及KeyError问题解决

解决Pandas中系统调用频次统计的行更新问题

先帮你理清楚问题所在:你之前的代码核心问题是Pandas索引和赋值的语法错误,而且逐行循环更新DataFrame其实不是Pandas的最优操作方式——我先给你一套高效的批量处理方案,再纠正你想要的逐行更新写法。

一、更高效的批量处理方案(推荐)

Pandas天生擅长批量操作,逐行循环在文件数量多、数据量大的时候会很慢。我们可以先把所有文件的数据读入并标记来源,再通过分组聚合直接算出结果:

import pandas as pd
import os

# 替换成你的目标文件夹路径
folder_path = "./syscall_files"
all_data = []

# 遍历文件夹里的所有文件
for filename in os.listdir(folder_path):
    file_path = os.path.join(folder_path, filename)
    # 读取单个文件,指定列名
    df_single = pd.read_csv(file_path, sep=" ", header=None, names=["syscall", "count"])
    # 添加文件名列,用于统计该系统调用出现在多少个文件中
    df_single["source_file"] = filename
    all_data.append(df_single)

# 合并所有文件的数据
combined_df = pd.concat(all_data, ignore_index=True)

# 分组计算:sum得到总频次,nunique得到出现的文件数
result = combined_df.groupby("syscall").agg(
    freq=("count", "sum"),
    file_freq=("source_file", "nunique")
).reset_index()

# 调整列顺序并输出
result = result[["syscall", "freq", "file_freq"]]
print(result.to_string(index=False))

这个方案的输出完全符合你的示例要求,而且效率比逐行循环高很多。

二、纠正你的逐行更新写法(如果坚持用循环)

你之前的代码有两个关键错误:

  1. 语法错误:df.(words[0],'frequency')这种写法完全不符合Pandas语法,应该用.loc来定位行和列
  2. 逻辑漏洞:同一个文件里的同一个系统调用,file_freq只能加1一次,不能每出现一行就加1

下面是修正后的逐行循环代码:

import pandas as pd
import os

folder_path = "./syscall_files"
# 初始化DataFrame,行索引设为系统调用名称,列是频次和文件数
df = pd.DataFrame(columns=["freq", "file_freq"], dtype=int)

for filename in os.listdir(folder_path):
    file_path = os.path.join(folder_path, filename)
    # 用集合记录当前文件已处理的系统调用,避免重复加file_freq
    handled_syscalls = set()
    
    with open(file_path, "r") as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            words = line.split()
            syscall = words[0]
            count = int(words[1])
            
            if syscall in df.index:
                # 已存在,更新总频次
                df.loc[syscall, "freq"] += count
                # 同一个文件里的系统调用,file_freq只加1一次
                if syscall not in handled_syscalls:
                    df.loc[syscall, "file_freq"] += 1
                    handled_syscalls.add(syscall)
            else:
                # 不存在,新增行
                df.loc[syscall] = [count, 1]
                handled_syscalls.add(syscall)

# 重置索引并调整列顺序输出
result = df.reset_index().rename(columns={"index": "syscall"})
print(result.to_string(index=False))

为什么你之前的代码会报错?

  • 第一个代码片段的df.(words[0],'frequency')是完全错误的语法,Pandas中定位行和列必须用df.loc[行索引, 列名]的格式
  • 第二个代码片段的df[words[0]]['frequency']是把系统调用名称当成了列名,但你的DataFrame列名是freq/file_freq,系统调用名称应该是行索引,所以会触发KeyError

内容的提问来源于stack exchange,提问作者ubuntu_noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:38:10