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

使用df.div和条件填充Pandas DataFrame列值未达预期

问题:正确计算股票拆分后的fractShrs列值

需求是将DataFrame中fractShrs列初始值设为1,当股份数量(numShrs)发生变化时,计算numShrs(t)/numShrs(t+1)作为新的fractShrs值,并保持该值直到下一次股份变化。例如示例中2023-07-06股份从150变为600,fractShrs应从1变为0.25并维持该值。

当前代码及问题

现有代码尝试通过掩码标记股份变化行,但计算结果不符合预期,变化行出现极小值而非目标值:

def populate_fraction_of_shares(df: pd.DataFrame) -> pd.DataFrame: 
    # 创建掩码标记numShrs变化的行
    mask = df['numShrs'] != df['numShrs'].shift()   

    # 仅对变化行应用除法
    df['fractShrs'] = df['numShrs'].div(df['numShrs'].shift().where(cond=mask, other=1))
    
    # 归一化,使最后一行值为1
    df['fractShrs'] = df['fractShrs'].div(df.iloc[-1]['numShrs'])

尝试修改other参数为当前numShrs也未解决问题:

df['fractShrs'] = df['numShrs'].div(df['numShrs'].shift().where(cond=mask, other=df['numShrs']))

示例DataFrame

VWAP    VWAPAdj country dividend    dividendAdj freeFloatPct    numShrs pxAsk   pxAskAdj    pxBid   pxBidAdj    pxHigh  pxHighAdj   pxLast  pxLastAdj   pxLow   pxLowAdj    returnIndex turnover    volume  isin    name    currency    fractShrs
date                                                                                                
2023-07-03  176.503682  176.503682  USA 1.00    1.00    94.0    150.00  176.352591  176.352591  176.343429  176.343429  177.644518  177.644518  176.343429  176.343429  175.702037  175.702037  193326.88   5.547447e+09    31458200.0  US0378331005    APPLE INC COM   EUR 1
2023-07-05  176.535496  176.535496  USA 1.00    1.00    94.0    150.00  176.292623  176.292623  176.283409  176.283409  177.812933  177.812933  176.292623  176.292623  175.638415  175.638415  192191.75   8.271696e+09    46920262.0  US0378331005    APPLE INC COM   EUR 1
2023-07-06  175.203695  175.203695  USA 1.00    1.00    94.0    600.00  176.125087  176.125087  176.106719  176.106719  176.345505  176.345505  176.152638  176.152638  173.755691  173.755691  192673.94   7.954350e+09    45156008.0  US0378331005    APPLE INC COM   EUR 1

解决方案

核心思路是计算股份变化点的调整因子,再通过累计乘积得到每个时间点的fractShrs值:

import pandas as pd

def populate_fraction_of_shares(df: pd.DataFrame) -> pd.DataFrame:
    # 复制原DataFrame避免修改原始数据
    df = df.copy()
    
    # 标记numShrs变化的行,第一行默认标记为变化(初始化)
    mask = df['numShrs'] != df['numShrs'].shift(fill_value=df['numShrs'].iloc[0])
    
    # 初始化调整因子列,默认值为1(无变化时保持上一因子)
    df['adjust_factor'] = 1.0
    
    # 在变化行计算调整因子:前一期股份数 / 当前股份数
    df.loc[mask, 'adjust_factor'] = df['numShrs'].shift() / df['numShrs']
    
    # 第一行调整因子设为1(初始值)
    df.loc[df.index[0], 'adjust_factor'] = 1.0
    
    # 累计乘积得到fractShrs,确保变化后的值持续到下一次变化
    df['fractShrs'] = df['adjust_factor'].cumprod()
    
    # 可选:若需最后一行值为1,执行归一化
    # df['fractShrs'] = df['fractShrs'] / df['fractShrs'].iloc[-1]
    
    # 删除临时调整因子列
    df = df.drop(columns=['adjust_factor'])
    
    return df

代码说明

  1. 掩码标记变化行:通过shift对比当前与前一期的numShrs,第一行用初始值填充避免NaN。
  2. 计算调整因子:变化行的因子为前一期numShrs / 当前numShrs,无变化时因子为1。
  3. 累计乘积:通过cumprod()将调整因子累计,确保变化后的fractShrs值持续到下一次股份变化。
  4. 可选归一化:如果需要最后一行值为1,可取消注释归一化代码。

预期结果

运行后示例DataFrame的fractShrs列值为:

  • 2023-07-03: 1
  • 2023-07-05: 1
  • 2023-07-06: 0.25

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:26:07