如何按column2分组统计每行之前同组行中值大于当前行的数量
按分组统计之前行中大于当前行的数量
首先修正你提供的全局实现代码的语法错误,正确的全局统计逻辑应该是:
import numpy as np import pandas as pd a = df['column1'].to_numpy() # 生成上三角矩阵(排除对角线,只统计之前的行),每行求和得到对应数量 df['lesser_count'] = np.triu(a < a[:, None], k=1).sum(axis=1)
要针对column2的每个分组单独执行这个统计逻辑,你可以用以下两种方式实现:
方法1:简洁的分组应用(适合中小数据集)
def count_previous_greater(group): a = group['column1'].to_numpy() # k=1确保只统计当前行之前的行,不包含自身 group['lesser_count'] = np.triu(a < a[:, None], k=1).sum(axis=1) return group # 按column2分组后应用统计逻辑 df = df.groupby('column2', group_keys=False).apply(count_previous_greater)
方法2:高效向量化实现(适合大规模数据集)
如果数据集较大,上述apply方法可能存在性能瓶颈,可以用以下方式避免分组循环开销:
# 给每个分组内的行标记顺序位置 df['group_pos'] = df.groupby('column2').cumcount() # 提取每个分组的数值和位置数组 grouped_vals = df.groupby('column2')['column1'].apply(np.array) grouped_pos = df.groupby('column2')['group_pos'].apply(np.array) # 遍历分组计算结果 results = [] for vals, pos in zip(grouped_vals, grouped_pos): # 生成仅保留当前行之前记录的掩码 mask = pos[:, None] > pos # 统计每个位置之前比当前值大的数量 counts = (vals[:, None] < vals)[mask].reshape(len(vals), -1).sum(axis=1) results.extend(counts) df['lesser_count'] = results df.drop('group_pos', axis=1, inplace=True)
说明:
np.triu(..., k=1)是核心逻辑,它通过上三角矩阵过滤掉当前行及之后的行,只统计之前的记录。- 方法1代码直观易维护;方法2通过向量化操作减少循环开销,处理大数据集时效率更高。
内容的提问来源于stack exchange,提问作者hadi ahmadi
相关产品推荐
相关产品推荐

