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

如何从Pandas DataFrame首个非NaN条目提取客户首次付款日期

解决思路
  • 第一步:先做数据结构转换,把12列的宽表月份数据转为长格式,让每一条记录对应「客户ID-年份-月份-付款金额」的结构,方便后续筛选排序
  • 第二步:过滤掉付款金额为空的记录,仅保留实际有付款的条目
  • 第三步:建立月份名称到数字的映射,避免按英文名称字母序排序出错,再按客户ID分组,取每个客户分组内年份最小、同年份内月份数字最小的记录
  • 第四步:补全所有原始客户ID,无有效付款记录的标记为「-」,最后按要求格式化日期输出
可运行示例代码
import pandas as pd

# 此处为模拟的和你场景一致的MultiIndex数据,实际使用时替换成你自己的df即可
ids = [1001,1001,1002,1003,1003]
years = [2021,2022,2022,2021,2022]
index = pd.MultiIndex.from_tuples(list(zip(ids,years)), names=['客户ID','付款年份'])
cols = ['January__c','February__c','March__c','April__c','May__c','June__c','July__c','August__c','September__c','October__c','November__c','December__c']
data = [
    [None, None, 300, None, None, None, None, None, None, None, None, None],
    [100, None, None, None, None, None, None, None, None, None, None, None],
    [None, None, None, None, None, None, None, None, None, None, None, None],
    [None, None, None, None, 500, None, None, None, None, None, None, None],
    [None, 200, None, None, None, None, None, None, None, None, None, None]
]
df = pd.DataFrame(data, index=index, columns=cols)

# 建立月份和数字的双向映射,用于排序和格式化输出
month_to_num = {
    'January':1, 'February':2, 'March':3, 'April':4, 'May':5, 'June':6,
    'July':7, 'August':8, 'September':9, 'October':10, 'November':11, 'December':12
}

# 1. 处理列名,转为长表结构
df_long = df.rename(columns=lambda x: x.replace('__c','')).stack(dropna=False).reset_index()
df_long.columns = ['客户ID','付款年份','月份','付款金额']

# 2. 过滤有付款的记录,添加排序用的月份数字列
df_valid_pay = df_long.dropna(subset=['付款金额']).copy()
df_valid_pay['month_order'] = df_valid_pay['月份'].map(month_to_num)

# 3. 按年份、月份排序后取每个客户的第一条记录,即为首次付款
first_pay = df_valid_pay.sort_values(['付款年份','month_order']).groupby('客户ID').first().reset_index()
first_pay['首次付款日期'] = first_pay['月份'] + ' ' + first_pay['付款年份'].astype(str)

# 4. 补全所有客户,无付款记录标记为-
all_customer_ids = df.index.get_level_values('客户ID').unique()
result = pd.DataFrame({'客户ID':all_customer_ids}).merge(
    first_pay[['客户ID','首次付款日期']], on='客户ID', how='left'
).fillna({'首次付款日期':'-'})
输出说明

最终得到的result即为符合要求的统计结果,以上示例的输出效果如下:

客户ID首次付款日期
1001March 2021
1002-
1003May 2021

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:45:04