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

如何在DataFrame指定行集上批量应用自定义公式?

批量处理DataFrame分段数据的线性拟合方案

看起来你已经完成了最关键的一步——定位出了分隔各个<PROFIEL>段的行位置(indicatie列表),现在只需要把这些位置转换成可批量处理的数据区间,就能自动对每个区间的x和y应用你的线性拟合函数了。我来给你整理一套可行的解决方案:

核心思路

你的indicatie列表里的数值是那些非<METING>的行索引(也就是每个<PROFIEL>的开头和结尾标记),其中连续的数值对(比如12和13、26和27)就是一个<PROFIEL>的首尾边界。我们需要把这些边界转换成中间有效数据段的索引范围,然后遍历每个范围自动调用rechtzetten函数。

完整实现代码

import pandas as pd
import numpy as np

# 读取数据源
df = pd.read_csv('Dalfsen.csv')

# 优化你的线性拟合函数:返回拟合结果和参数,方便后续分析
def rechtzetten(x, y):
    n = len(x)
    # 避免除数为0的情况(比如x全相同)
    denominator = n * np.sum(x**2) - np.sum(x)**2
    if denominator == 0:
        print("警告:x值全部相同,无法拟合直线")
        return None, None, None
    a = (n * np.sum(x*y) - np.sum(x)*np.sum(y)) / denominator
    b = (np.sum(y) - a * np.sum(x)) / n
    y_fit = x * a + b
    print(f"拟合参数 a: {a:.4f}, b: {b:.4f}")
    return y_fit, a, b

# 定位非<METING>的行(即分隔行)
METING = df.ID.str.contains("<METING>")
indicatie = np.where(METING == False)[0]

# 生成需要处理的有效数据区间
intervals = []
i = 0
total_separators = len(indicatie)
while i < total_separators - 1:
    current_sep = indicatie[i]
    next_sep = indicatie[i+1]
    # 如果两个分隔行是连续的,说明是一个<PROFIEL>的首尾,跳过这对
    if next_sep == current_sep + 1:
        i += 2
    else:
        # 有效数据段是从当前分隔行的下一行,到下一个分隔行的前一行
        start_idx = current_sep + 1
        end_idx = next_sep - 1
        intervals.append((start_idx, end_idx))
        i += 1

# 遍历所有区间,批量应用拟合函数
fit_results = []
for seg_num, (start, end) in enumerate(intervals, 1):
    print(f"\n=== 处理第 {seg_num} 个数据段(索引范围: [{start}, {end}]) ===")
    # 提取当前段的x和y值
    x_data = df.loc[start:end, 'x'].values
    y_data = df.loc[start:end, 'y'].values
    
    # 确保数据段有足够的点(至少2个点才能拟合直线)
    if len(x_data) < 2:
        print("数据段点数不足,跳过拟合")
        continue
    
    # 调用拟合函数
    y_fitted, a_param, b_param = rechtzetten(x_data, y_data)
    if y_fitted is not None:
        fit_results.append({
            "segment_number": seg_num,
            "start_index": start,
            "end_index": end,
            "slope_a": a_param,
            "intercept_b": b_param,
            "fitted_y": y_fitted
        })

# 可选:把结果转换成DataFrame,方便查看和导出
results_df = pd.DataFrame(fit_results)
print("\n=== 所有拟合结果汇总 ===")
print(results_df[["segment_number", "start_index", "end_index", "slope_a", "intercept_b"]])

代码细节说明

  1. 区间生成逻辑:通过循环遍历indicatie列表,跳过连续的分隔行对(这些是<PROFIEL>的首尾标记),自动提取中间的有效数据段索引范围,完全不需要手动写[1:11]这类区间。
  2. 函数优化:增加了除数为0的异常处理(比如x值全部相同的情况),同时返回拟合结果和参数,方便后续保存或进一步分析。
  3. 边界检查:添加了数据段点数判断,避免因为点数不足导致的计算错误。
  4. 结果保存:把每个段的拟合结果存储在列表中,最后可以转换成DataFrame统一查看,也可以导出为CSV文件(比如results_df.to_csv("fit_results.csv", index=False))。

示例运行效果

假设某个数据段有足够的有效数据,会输出类似这样的内容:

=== 处理第 1 个数据段(索引范围: [1, 11]) ===
拟合参数 a: 0.8765, b: 2.3456

=== 处理第 2 个数据段(索引范围: [14, 25]) ===
拟合参数 a: -1.2345, b: 6.7890

=== 所有拟合结果汇总 ===
   segment_number  start_index  end_index  slope_a  intercept_b
0               1            1         11   0.8765        2.3456
1               2           14         25  -1.2345        6.7890

这样就能完全替代你手动编写几百次重复代码的工作啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 00:49:06