在指定的 Pandas 日期范围内使用 Python math.prod()

问题描述 投票:0回答:1

我对 Python 比较陌生,但我有一个复杂的问题,我认为需要一些不同的函数,但我不知道从哪里开始。

在 Excel 中,通过使用 PRODUCT 函数,基于到最近续订日期的起点(在本例中为 01/10/2020),然后简单地乘以每个产品的 Product 函数总计,这在 Excel 中非常简单。起始点元素的数量,给出当前更新日期总计,按元素值细分。

我想用 Python 写这个,但是除了 Python 3.8 math.prod() 的基本信息之外,我似乎无法在网上找到更多的信息来解决/帮助我解决这个问题。

我有以下 3 个 Pandas 数据框(为了便于解释,我从 Excel 复制了数据并粘贴到下面的链接中,但我已将它们作为数据框导入到我的测试代码中)。

数据采用这种形式,需要整理在一起,并根据会员权利的不同元素进行重新评估,需要从开始日期(“StartDate”)到当前“续订”日期(01/ 10/2020) - 如果可能,还需要在 StartDate 到第一个续订日期之间的完整月份中按比例完成(相当于 Excel YEARFRAC 函数)。

这 3 个数据框是:

  1. 具有一定基本信息的会员身份标识。最重要的数据是“StartDate”列,因为它是重新评估会员福利的关键。我猜它需要有一个函数来计算从 StartDate 到会员的第一次续订日期的 TimeDelta(以月为单位),这需要按比例计算差值,例如第一个会员于 2016 年 1 月 2 日开始,因此第一次续约需要按比例分配 8 个月。我还想设置一个布尔值,如果为 True,则按比例发生,否则不会

List of MemberIDs and StartDates

  1. 增加因素。这些元素会增加或保持水平(价值不会减少)

Increase rates by year (index used is the Renewal Date)

  1. 会员资产 - 通过会员标识符 (MemberID) 链接到 (1)。这些不同的元素应按 (2) 中的增加因子逐步升级,这些数字是开始日期时的元素。

StartDate elements

本质上,函数需要计算第一个续订日期在 StartDate 之后的时间,如果布尔值为 True,则应用按比例增加,然后计算出续订日期的范围并增加 StartDate 和最新日期之间的系数续订日期,并最终在 StartDate 元素上应用此日期范围的产品。

这是我的第一篇文章,如果它不符合您可能期望的格式或任何 Python 代码,我深表歉意,因为我对 Python 和 StackOverflow 非常陌生(他们甚至不允许我直接发布表格,仅作为图像链接)。由于数据保护,我提供的数据是虚拟日期,但相对基于实际数据。

您有任何疑问,我很乐意提供更多信息。感谢您提前提供任何帮助!

编辑: 请参阅我正在使用的临时解决方案,但它没有按 StartDate 到第一次增加日期之间第一次增加的比例: Solution (without pro-rata)

  • 示例中的 MemberID,Python 函数应该找到 StartDate 之后的第一次增加,即 01/10/2016 (DD/MM/YYYY)
  • 然后,该函数应检查续订日期在 01/10/2016 和最新续订日期 01/10/2020 之间按每个元素增加。 Excel PRODUCT 公式给出的元素增量为:元素 1 到 3 分别为 1.38823、1.20396 和 1.20462
  • 最后,将 StartDate 中的元素乘以每个批次的 Product 总数,得到当前值
python python-3.x pandas dataframe python-datetime
1个回答
1
投票

我在这里整理了一些内容,应该可以为您提供入门知识。第一个代码块只是重新创建您的数据。第二个块迭代每个成员,获取适当的更新日期,然后将获取的行与 DataFrame 相乘。

由于使用成员 ID 上的显式 for 循环而不是广播,它的效率并不高,但它应该可以帮助您入门。

import pandas as pd

df_startDate = pd.DataFrame({
    'StartDate': pd.to_datetime(['01/02/2016', '10/04/2017', '29/09/2018', '05/11/2018']),
}, index=['9000001', '9000023', '9004561', '9007910'])

df_renewals = pd.DataFrame({
    'Element 1': [1.05, 1.04, 1.06, 1.10, 1.08, 1.06],
    'Element 2': [1.03, 1.02, 1.07, 1.05, 1.03, 1.02],
    'Element 3': [1.04, 1.04, 1.05, 1.03, 1.02, 1.05],
}, index=pd.to_datetime(['01/10/'+str(i) for i in range(2015, 2021)]))

df_assets = pd.DataFrame({
    'Element 1': [1000, 1500, 2000, 1750],
    'Element 2': [1500, 2000, 2500, 2000],
    'Element 3': [2000, 2500, 3000, 2250],
}, index=['9000001', '9000023', '9004561', '9007910'])

print(df_startDate)
print(df_renewals)
print(df_assets)

我的方法你可以学习:

results = pd.DataFrame(columns=['Element 1', 'Element 2', 'Element 3'])

for member_id in df_startDate.index:
    print('******')
    print(member_id)
    
    # Get rows between the StartDate and the current date
    df_factors = df_renewals.loc[df_startDate['StartDate'].loc[member_id]: pd.Timestamp.now()]
    print(df_factors, end='\n\n')
    
    # Multiply rows together to get total factor
    prod_factors = df_factors.product(axis='index')
    print(prod_factors.to_frame().T, end='\n\n')
    
    # Multiply factor with base value
    results.loc[member_id] = df_assets.loc[member_id].mul(prod_factors)
    print(results.loc[member_id].to_frame().T, end='\n\n')

print(results)

无注释/打印:

results = pd.DataFrame(columns=['Element 1', 'Element 2', 'Element 3'])
for member_id in df_startDate.index:
    df_factors = df_renewals.loc[df_startDate['StartDate'].loc[member_id]: pd.Timestamp.now()]
    results.loc[member_id] = df_assets.loc[member_id].mul( df_factors.product(axis='index') )

结果:

           Element 1    Element 2   Element 3
9000001  1388.230272  1805.934123  2409.23592
9000023  1888.920000  2206.260000  2757.82500
9004561  2289.600000  2626.500000  3213.00000
9007910  2003.400000  2101.200000  2409.75000
© www.soinside.com 2019 - 2024. All rights reserved.