基于行中轴信息计算斜率:如何为DataFrame的每组Name-Segment添加逐点斜率行?
为分组DataFrame添加斜率行的解决方案
嘿,我来帮你搞定这个需求!首先得理清楚咱们的目标:给每个Name-Segment分组加一行Slope,计算每个数据点的Δy/Δx。咱们一步步来实现:
第一步:规整原DataFrame的结构
原数据里Name和Segment列有不少空值,这是合并单元格的显示形式,但处理数据时得先把这些空值填上,才能准确分组。用ffill()(向前填充)就能轻松搞定:
import pandas as pd # 先构造原DataFrame data = { 'Name': ['Amazon', '', 'Amazon', ''], 'Segment': [1, '', 2, ''], 'Axis': ['x', 'y', 'x', 'y'], 1: [0, 0, 0, 0], 2: [1, 0.4, 2, 1], 3: [2, 0.8, 4, 2], 4: [3, 1.2, 6, 3], 5: [4, 1.6, 8, 4] } df = pd.DataFrame(data) # 填充Name和Segment的空值,让每组的所有行都有分组标识 df[['Name', 'Segment']] = df[['Name', 'Segment']].ffill()
第二步:分组计算斜率并构造Slope行
接下来按Name和Segment分组,对每个组做以下操作:
- 提取x轴和y轴的数值数据(列1到5)
- 计算相邻点的斜率:Δy/Δx,用
diff()函数计算变化量后相除,第一列留空(因为没有前一个参考点) - 把计算好的斜率做成新的
Slope行,加入到组里
代码如下:
# 存储处理后的所有行数据 processed_rows = [] # 遍历每个Name-Segment分组 for (name, segment), group in df.groupby(['Name', 'Segment']): # 提取当前组的x、y数值 x_vals = group[group['Axis'] == 'x'].iloc[0, 3:].values y_vals = group[group['Axis'] == 'y'].iloc[0, 3:].values # 计算相邻点的斜率:Δy/Δx delta_y = pd.Series(y_vals).diff().values delta_x = pd.Series(x_vals).diff().values slope_vals = delta_y / delta_x # 构造Slope行的字典数据 slope_row = { 'Name': name, 'Segment': segment, 'Axis': 'Slope', 1: None, 2: slope_vals[0], 3: slope_vals[1], 4: slope_vals[2], 5: slope_vals[3] } # 把原组的行和新的Slope行加入结果列表 processed_rows.extend(group.to_dict('records')) processed_rows.append(slope_row) # 转换成最终的DataFrame result_df = pd.DataFrame(processed_rows)
第三步:还原合并单元格的显示样式
如果想要和原数据一样,把Name和Segment列的重复值设为空,显示时就会呈现合并单元格的效果:
# 将重复的Name和Segment值设为空字符串 result_df['Name'] = result_df['Name'].mask(result_df['Name'].duplicated(), '') result_df['Segment'] = result_df['Segment'].mask(result_df['Segment'].duplicated(), '') # 打印查看结果 print(result_df.to_string(index=False))
运行后得到的结果完全符合你的预期:第一组的斜率全为0.4,第二组全为0.5,结构和你给出的示例一致。
补充:如果需要计算相对初始点的斜率
要是你的需求是计算每个点相对于第一个点的斜率(而非相邻点),只需把斜率计算部分改成:
# 计算每个点相对于初始点的斜率 slope_vals = (y_vals - y_vals[0]) / (x_vals - x_vals[0]) # 初始点的斜率设为空 slope_vals[0] = None
内容的提问来源于stack exchange,提问作者tj judge
相关产品推荐
相关产品推荐

