基于另一DataFrame生成递增分配值的新列技术实现求助
实现方案
嘿,这个需求用 pandas 其实很好实现,我给你拆解成具体步骤和代码示例,你可以根据自己的实际需求调整细节:
核心思路
- 先把 df1 和 df2 按
F_Date合并,让 df1 的每一行都能拿到对应F_Date的Value; - 按
F_Date分组,针对每个组的记录数,生成符合要求的递增序列,赋值给新增的value_1列。
具体代码示例
第一步:准备模拟数据(你可以替换成自己的真实数据)
import pandas as pd import numpy as np # 模拟你的df1:每个F_Date对应多条B_Date df1 = pd.DataFrame({ 'F_Date': ['01/09/2019']*51 + ['02/09/2019']*20, 'B_Date': pd.date_range('2019-09-01', periods=71) }) # 模拟你的df2:每个F_Date对应唯一Value df2 = pd.DataFrame({ 'F_Date': ['01/09/2019', '02/09/2019'], 'Value': [3000, 1500] })
第二步:合并两个DataFrame
把 df2 里的 Value 匹配到 df1 对应的 F_Date 行:
df_merged = pd.merge(df1, df2, on='F_Date', how='left')
第三步:生成递增序列(三种常见方式可选)
根据你对“递增”的具体要求,这里提供三种常用实现:
方式1:线性递增到目标Value(最后一条等于df2的Value)
适合想要序列从0开始,最终到达 Value 的场景:
def linear_increase(group): record_count = len(group) target_value = group['Value'].iloc[0] # 生成从0到target_value的线性序列,共record_count个值 return pd.Series(np.linspace(0, target_value, num=record_count), index=group.index) # 应用到每个F_Date分组 df_merged['value_1'] = df_merged.groupby('F_Date').apply(linear_increase).reset_index(drop=True)
方式2:固定步长递增(总增量等于Value)
适合想要起始值自定义,每条按固定步长增加,最后一条比第一条多 Value 的场景:
def step_increase(group): record_count = len(group) total_increment = group['Value'].iloc[0] start_value = 100 # 你可以改成自己需要的起始值 if record_count == 1: step = 0 else: step = total_increment / (record_count - 1) # 生成起始值+步长*序号的序列 return pd.Series([start_value + i*step for i in range(record_count)], index=group.index) df_merged['value_1'] = df_merged.groupby('F_Date').apply(step_increase).reset_index(drop=True)
方式3:等比递增(增长速度越来越快)
适合需要数值增长幅度逐渐变大的场景:
def geometric_increase(group): record_count = len(group) target_value = group['Value'].iloc[0] # 生成从1到target_value的等比序列,共record_count个值 return pd.Series(np.geomspace(1, target_value, num=record_count), index=group.index) df_merged['value_1'] = df_merged.groupby('F_Date').apply(geometric_increase).reset_index(drop=True)
额外提示
因为你提到 df1 已经按 F_Date 排序了,所以分组后的序列顺序就是原数据的顺序。如果需要确保按 B_Date 的顺序递增,可以先做一次排序:
df_merged = df_merged.sort_values(['F_Date', 'B_Date']).reset_index(drop=True)
内容的提问来源于stack exchange,提问作者vp7
相关产品推荐
相关产品推荐

