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

如何在Pandas中无需循环计算数据的所有可能组合的和?

不用循环计算Pandas Series所有非空组合的和

嘿,你这个问题问得好!用itertools.combinations加循环逐个求和确实有点繁琐,数据量大的时候效率也上不去。其实我们可以借助numpy的向量化特性,完全避开显式循环来实现,下面给你两种靠谱的方法:

方法一:numpy组合生成 + 向量化求和

这种方法还是会用到itertools.combinations生成组合,但求和环节用numpy的向量化操作替代循环,速度会快很多:

import pandas as pd
import itertools as it
import numpy as np

A = pd.Series([50, 20, 75], index=list(range(1, 4)))
arr = A.values

all_sums = []
for combo_length in range(1, len(arr)+1):
    # 一次性生成所有当前长度的组合,转成二维数组后直接按行求和
    combo_arr = np.array(list(it.combinations(arr, combo_length)))
    all_sums.extend(combo_arr.sum(axis=1))

# 转成Series方便查看和后续处理
result = pd.Series(all_sums)
print(result)

这里虽然还有个循环遍历组合长度,但已经没有了逐个组合求和的内层循环,求和是numpy的批量操作,比纯Python循环高效得多。

方法二:二进制掩码法(完全无显式循环)

这个思路更巧妙,利用二进制数的每一位代表是否选中对应元素,生成所有非空子集的掩码,然后通过矩阵运算直接求和,全程没有显式循环:

import pandas as pd
import numpy as np

A = pd.Series([50, 20, 75], index=list(range(1, 4)))
arr = A.values
element_count = len(arr)

# 生成1到2^n -1的所有整数,每个整数对应一个非空子集
mask_numbers = np.arange(1, 2**element_count)[:, np.newaxis]
# 把整数转成布尔掩码矩阵,每行对应一个子集的元素选中情况
binary_masks = (mask_numbers & (1 << np.arange(element_count))) != 0
# 用掩码和原数组做点积,直接得到所有组合的和
all_sums = binary_masks.dot(arr)

result = pd.Series(all_sums)
print(result)

简单解释下逻辑:

  • 1 << np.arange(element_count)生成2的幂次数组,用来提取每个整数的二进制位
  • (mask_numbers & ...) !=0把整数转成布尔矩阵,每一行的True就表示对应位置的元素被选中
  • dot(arr)相当于对每行选中的元素求和,一步到位完成所有计算

结果验证

两种方法得到的结果都和你原来的循环方法一致:

0     50
1     20
2     75
3     70
4    125
5     95
6    145
dtype: int64

如果你的数据量比较大,第二种方法的优势会更明显,因为numpy的向量化运算比Python循环快几个数量级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:20:42