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

在DataFrame中剔除超出比值阈值范围的粒子数据

问题描述

初始数据:
输入图片描述

原始代码:

import pandas as pd
import numpy as np

d = {'RedVal':[1,1.1,2,1.5,1.7,2,1,1.1,2,1,1.1,2,2.6,2.5,2.4,2.5], 
     'GreenVal':[1,1.1,1.1,1,1.1,1.7,1,1.1,1.5,1,1.9,3,2.8,2.7,2.6,2.5],
     'Frame':[0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3],
     'Particle':[0,0,0,0,2,2,2,2,3,3,3,3,4,4,4,4] }
testframe = pd.DataFrame(data=d)

framenot = 2  #set how many frames you would like to get initial ratio for
ratarray = [] #initialize blank ratio array
testframe.sort_values(by =[ 'Particle', 'Frame'])
for particle in range(0,5):
    if(testframe['Particle']== particle).any() == False:
        particle = particle + 1
    else:
        newframe = testframe.loc[(testframe['Frame']<= framenot) & (testframe['Particle'] == particle)]
        for i in range(framenot):
            GVal = newframe['GreenVal'].values[i]
            RVal = newframe['RedVal'].values[i]
            ratio = RVal/GVal
            ratarray.append(ratio)
            i+=1
        particle+=1
ratarray = np.array(ratarray)
avgRatios = np.average(ratarray.reshape(-1,framenot), axis = 1)
stdRatios = np.std(ratarray.reshape(-1,framenot), axis = 1)
print(avgRatios) #array with average ratios over set frames starting from initial particle
print(stdRatios)

目前上述代码可计算每个粒子在Frame 0和1的RedVal/GreenVal比值的平均值(avgRatios)与标准差(stdRatios)。现需将该平均比值与后续x帧的比值进行对比,剔除后续帧比值超出“平均值±2倍标准差”范围的粒子,求实现方法。

实现方案

步骤说明

  1. 为每个粒子的所有帧计算RedVal/GreenVal比值,新增列到DataFrame
  2. 用分组计算替代原循环,高效获取每个粒子初始帧(Frame0-1)的平均比值和标准差
  3. 定义后续帧范围(示例为Frame≥2,可按需调整x值)
  4. 检查每个粒子的后续帧比值是否全部在允许区间内,筛选符合条件的粒子

代码实现

import pandas as pd
import numpy as np

# 1. 构建数据并计算所有帧的比值
d = {'RedVal':[1,1.1,2,1.5,1.7,2,1,1.1,2,1,1.1,2,2.6,2.5,2.4,2.5], 
     'GreenVal':[1,1.1,1.1,1,1.1,1.7,1,1.1,1.5,1,1.9,3,2.8,2.7,2.6,2.5],
     'Frame':[0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3],
     'Particle':[0,0,0,0,2,2,2,2,3,3,3,3,4,4,4,4] }
testframe = pd.DataFrame(data=d)
testframe['Ratio'] = testframe['RedVal'] / testframe['GreenVal']  # 新增比值列

# 2. 分组计算每个粒子初始帧的平均和标准差
framenot = 2  # 初始帧范围:Frame < framenot(即0和1)
init_stats = testframe[testframe['Frame'] < framenot].groupby('Particle').agg(
    AvgRatio=('Ratio', 'mean'),
    StdRatio=('Ratio', 'std')
).reset_index()

# 3. 定义后续帧范围(示例:Frame >=2,可替换为Frame >= framenot到Frame <= framenot+x)
x_frames = testframe[testframe['Frame'] >= framenot]

# 4. 合并初始统计和后续帧数据,检查比值是否在允许区间内
merged = pd.merge(x_frames, init_stats, on='Particle')
merged['IsWithinRange'] = (merged['Ratio'] >= merged['AvgRatio'] - 2*merged['StdRatio']) & \
                          (merged['Ratio'] <= merged['AvgRatio'] + 2*merged['StdRatio'])

# 筛选出后续帧所有比值都在范围内的粒子
valid_particles = merged.groupby('Particle')['IsWithinRange'].all()
valid_particles = valid_particles[valid_particles].index.tolist()

# 输出结果
print("符合条件的粒子ID:", valid_particles)
# 可选:输出符合条件的粒子所有数据
print("\n符合条件的粒子完整数据:")
print(testframe[testframe['Particle'].isin(valid_particles)])

关键说明

  • 若需求是只要后续有任意一帧超出范围就剔除,则用all();若需求是只要有一帧在范围内就保留,则替换为any()
  • 后续帧范围可灵活调整,比如要对比后续3帧(Frame2-4),可改为testframe[(testframe['Frame'] >= framenot) & (testframe['Frame'] <= framenot + 2)]
  • 原代码中的循环被groupby替代,代码更简洁且性能更优

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:05:21