Pandas序列同符号值累积连续计数及符号变化时长技术问询
Pandas符号相关统计与代码优化方案
1. Pandas Series中同符号值的累积与连续计数
咱们可以分两步实现:连续计数(当前连续同符号的元素个数)和累积同符号值的求和,具体代码如下:
示例代码
import pandas as pd import numpy as np # 测试数据 s = pd.Series([1, -4, 5, 1, -2, -4, 1, 3, 2, -4, -5, -5, -6, -1]) # 1. 计算每个元素的符号 signs = np.sign(s) # 2. 生成同符号连续组的标签(符号变化时组ID递增) continuous_groups = (signs != signs.shift()).cumsum() # 3. 连续计数:每个组内从1开始计数 continuous_count = continuous_groups.groupby(continuous_groups).cumcount() + 1 # 4. 累积同符号值的和:每个组内的累积求和 cumulative_sign_sum = s.groupby(continuous_groups).cumsum() # 合并结果 result = pd.DataFrame({ 'original_value': s, 'sign': signs, 'continuous_count': continuous_count, 'cumulative_sign_sum': cumulative_sign_sum }) print(result)
结果说明
continuous_count:记录当前元素所在的连续同符号序列的长度,比如第3个元素(值为5)是连续第1个正数值,第4个元素(值为1)是连续第2个正数值。cumulative_sign_sum:累积当前连续同符号组内的数值和,比如连续两个正值5+1=6,对应第4个元素的累积和就是6。
2. 符号变化后时长计算的代码优化
你的原始代码用循环结合np.where实现,虽然逻辑正确,但时间复杂度是O(n²),当数据量较大(比如上万行)时会非常慢。咱们可以用向量化的方式重构,把时间复杂度降到O(n),效率提升明显。
优化思路
- 先通过符号变化生成连续同符号组;
- 记录每个组的最后一个索引,通过
shift获取前一个不同符号组的最后索引; - 用当前索引减去前一个不同符号组的最后索引,得到时长。
优化后代码
import pandas as pd import numpy as np df = pd.DataFrame({'x': [1, -4, 5, 1, -2, -4, 1, 3, 2, -4, -5, -5, -6, -1]}) for column in df.columns: signs = np.sign(df[column]) # 生成连续同符号组标签 groups = (signs != signs.shift()).cumsum() # 获取每个组的最后索引,shift后得到前一个不同符号组的最后索引 prev_group_last_idx = df.groupby(groups).apply(lambda x: x.index[-1]).shift().fillna(0).astype(int) # 映射每个元素对应的前一个不同符号组的最后索引 last_diff_pos = groups.map(prev_group_last_idx) # 计算时长 df[f'{column}_days_since_sign_change'] = df.index - last_diff_pos print(df)
优化效果
- 避免了循环内的切片和
np.where操作,完全用Pandas的向量化方法处理; - 数据量越大,优化效果越明显:比如10万行数据,原始代码可能需要几分钟,优化后只需要几毫秒。
验证结果
优化后的代码和你的原始代码输出结果完全一致,比如第3个元素(索引3)的时长是2,第8个元素(索引8)的时长是3,和你的逻辑完全匹配。
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

