如何在Python DataFrame中提取最后一次符号变更后的所有行?
解决方案
步骤说明
- 计算每行值的符号(用
np.sign(),0的符号标记为0) - 标记符号发生变化的行:当前行符号与前一行不同则标记为True,第一行无前置行,标记为False
- 定位最后一次符号变化的索引,从该索引开始到末尾的行即为目标数据;若所有行符号一致,直接返回原DataFrame
完整代码
import numpy as np import pandas as pd # 生成示例数据 df = pd.DataFrame(np.random.randint(-10,10,size=(100, 1)), columns=list('v')) # 计算每行值的符号 signs = df['v'].apply(np.sign) # 标记符号变化的行 sign_changes = signs.ne(signs.shift()).fillna(False) # 获取所有符号变化的索引 change_indices = df[sign_changes].index # 提取目标数据 if len(change_indices) > 0: result_df = df.loc[change_indices[-1]:] else: result_df = df.copy() # 查看结果 print(result_df)
零值特殊处理(匹配示例需求)
如果需要将零值视为继承前一个非零值的符号(比如示例中95行的0归为正号),可以修改符号计算逻辑:
def get_inherited_sign(val, prev_sign): if val != 0: return np.sign(val) else: return prev_sign # 迭代生成符号序列,零值继承前一个非零值的符号 signs = [] prev_sign = 0 for val in df['v']: if val != 0: prev_sign = np.sign(val) signs.append(prev_sign) signs = pd.Series(signs, index=df.index) # 后续符号变更检测与数据提取步骤同上 sign_changes = signs.ne(signs.shift()).fillna(False) change_indices = df[sign_changes].index if len(change_indices) > 0: result_df = df.loc[change_indices[-1]:] else: result_df = df.copy()
这种处理下,示例中95行的0会被视为正号,96行的-1才会被判定为符号变更点,最终提取96-98行,完全匹配需求。
内容的提问来源于stack exchange,提问作者user176301
相关产品推荐
相关产品推荐

