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

如何统计DataFrame中b列值对应a列前置唯一值中≤它的数量?

问题需求

需要给DataFrame新增一列x,规则是:将b列的每个值与a列中该行及之前的所有唯一值对比,统计其中小于等于该值的唯一值数量。

示例DataFrame

import pandas as pd
df = pd.DataFrame(
    {
        'a': [100, 100, 105, 106, 106, 107, 108, 109],
        'b': [99, 100, 110, 107, 100, 110, 120, 106],
    }
)

预期输出

a    b    x
0  100   99    0
1  100  100    1
2  105  110    2
3  106  107    3
4  106  100    1
5  107  110    4
6  108  120    5
7  109  106    3

逻辑说明

  • 索引1行:b值为100,该行及之前a列的唯一值只有100,统计≤100的数量为1,故x=1
  • 索引2行:b值为110,该行及之前a列的唯一值是100、105,均≤110,故x=2
  • 其余行逻辑以此类推

用户尝试的代码(无法正常运行)

t = df.a.unique()
m1 = np.arange(len(t))[:,None] >= np.arange(len(t))

h = df['b'].to_numpy()
m2 = t <= h[:, None]

解决方案

方法1:循环追踪唯一值(直观易懂)

通过逐行维护a列的唯一值集合,再统计符合条件的数量:

import pandas as pd

# 初始化唯一值集合和结果列表
unique_a_set = set()
x_results = []

for a_val, b_val in zip(df['a'], df['b']):
    unique_a_set.add(a_val)
    # 统计集合中≤当前b值的元素数量
    count = sum(1 for num in unique_a_set if num <= b_val)
    x_results.append(count)

df['x'] = x_results
print(df)

方法2:向量化优化(适合大数据集)

利用numpy的向量化操作提升效率,避免循环:

import pandas as pd
import numpy as np

# 获取a列唯一值及其首次出现的索引
unique_vals, first_indices = np.unique(df['a'], return_index=True)
# 按首次出现顺序排序唯一值
sorted_unique = unique_vals[np.argsort(first_indices)]

# 生成每行对应的唯一值掩码:标记哪些唯一值在该行及之前出现过
mask = first_indices[:, None] <= np.arange(len(df))
# 对每行统计符合条件的唯一值数量
df['x'] = np.array([sum(sorted_unique[mask[:, i]] <= b) for i, b in enumerate(df['b'])])
print(df)

方法3:使用pandas expanding窗口

借助pandas的滚动窗口特性处理每行的历史数据:

import pandas as pd

def count_qualified_unique(window, b_val):
    unique_in_window = window.unique()
    return sum(unique_in_window <= b_val)

# 逐行处理expanding窗口内的a列数据
df['x'] = [count_qualified_unique(df['a'][:i+1], df['b'][i]) for i in range(len(df))]
print(df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:13:24