如何以嵌套方式对Pandas Series执行运算?高效替代循环方案
嘿,这个需求很常见!你想要的其实是两个Series的笛卡尔积式元素运算——也就是让第一个Series的每个元素都和第二个Series的所有元素运算一遍,完全不用低效的for循环,用Pandas或NumPy就能高效搞定,还能轻松扩展到其他函数。
先解决乘法的需求
方法1:用Pandas的交叉合并(直观易读)
从Pandas 1.2.0版本开始,支持how='cross'的合并方式,可以直接生成两个Series的笛卡尔积,之后再做乘法就行:
import pandas as pd s1 = pd.Series([1, 2, 3], name='num1') s2 = pd.Series([4, 5, 6], name='num2') # 生成笛卡尔积DataFrame cross_product = pd.merge(s1, s2, how='cross') # 计算乘积并重置索引 result = cross_product['num1'] * cross_product['num2'] print(result.reset_index(drop=True))
输出就是你想要的:
0 4 1 5 2 6 3 8 4 10 5 12 6 12 7 15 8 18 dtype: int64
方法2:用NumPy广播(性能最优,适合大数据集)
NumPy的广播机制可以把一维数组扩展成二维矩阵,做外积之后再展平,底层是C实现的向量化操作,速度比Pandas合并快很多,大数据集下优势明显:
import pandas as pd import numpy as np s1 = pd.Series([1, 2, 3]) s2 = pd.Series([4, 5, 6]) # 用广播生成外积矩阵,再展平成一维Series result = pd.Series((s1.values[:, np.newaxis] * s2.values).ravel()) print(result)
这个方法的输出和上面完全一致,但处理百万级别的数据时,速度会比for循环快几十倍甚至上百倍。
扩展到其他函数
不管是加法、除法这类内置运算,还是自定义函数,都可以用上面的思路实现:
示例1:加法运算
result_add = pd.Series((s1.values[:, np.newaxis] + s2.values).ravel())
示例2:自定义函数(比如计算两数平方和)
def calc_square_sum(x, y): return x**2 + y**2 result_custom = pd.Series(calc_square_sum(s1.values[:, np.newaxis], s2.values).ravel())
只要你的自定义函数支持NumPy数组的向量化操作,就能直接套用这个模式。
为什么不用for循环?
Python的for循环是逐元素迭代,每次迭代都有Python层面的开销,而NumPy/Pandas的向量化操作是把整个数组交给底层C代码批量处理,没有循环开销,大数据集下的性能差距会非常夸张——比如处理100万元素的Series,向量化操作可能几秒完成,for循环要跑几分钟甚至更久。
内容的提问来源于stack exchange,提问作者Hakan Utku Özdemir
相关产品推荐
相关产品推荐

