如何在pandas中计算带有NaN值的时间差

3

我对Pandas相对较新,已经尝试过搜索,但没有找到解决方案。 我有一个包含交易编号、客户编号和购买日期的数据框,看起来像这样:

Transaction   12345    12346       12347     12348       12349
customerID
1             NaN    2019-09-01    NaN     2019-09-11      2019-09-22...
2           2019-10-01 NaN         NaN         NaN      2019-10-07...
3    ...

数据框中有[6334行 x 8557列]。每一行都有NaN值,因为交易号是唯一的。
我想计算每一行的日期差异,以便得到
customerID    Datedifference1    Datedifference2     etc.
1                10                    11
2                 6
3   ...

我正在苦苦尝试获取每个客户的日期差异列表。 是否有一种方法可以忽略数据框中的NaN,仅在非NaN的值上计算? 我想要一个包含customerId和购买1和2之间、2和3之间等日期差异的列表,以估计下一次购买发生的天数。

是否有解决办法?

1个回答

1

这个想法是通过 DataFrame.stack 重新塑造数据,然后获取差异,按组删除第一个缺失值,最后再进行重塑:

df = df.apply(pd.to_datetime)

df1 = (df.stack()
         .groupby(level=0)
         .diff()
         .dropna()
         .dt.days
         .reset_index(level=1, drop=True)
         .to_frame())

df1 = (df1.set_index(df1.groupby(['customerID']).cumcount(), append=True)[0]
          .unstack()
          .add_prefix('Datedifference'))
print (df1)
             Datedifference0  Datedifference1
Transaction                                  
1                       10.0             11.0
2                        6.0              NaN

编辑:如果输入数据不同,则解决方案将改变-将列转换为日期时间,通过 DataFrameGroupBy.diff 创建新列以获取差异,通过 DataFrame.dropna 仅删除 NaN 行,并最后使用 DataFrame.set_indexunstack 与计数器 Series 一起使用 GroupBy.cumcount 进行重塑:

print (df1)
   customerID Transaction       date
0           1       12346 2019-09-01
1           1       12348 2019-09-11
2           1       12349 2019-09-22
3           2       12345 2019-10-01
4           2       12349 2019-10-07

df1['date'] = pd.to_datetime(df1['date'])
df1['diff'] = df1.groupby('customerID')['date'].diff().dt.days
df1 = df1.dropna(subset=['diff'])

df2 = (df1.set_index(['customerID', df1.groupby('customerID').cumcount()])['diff']
          .unstack()
          .add_prefix('Datedifference'))
print (df2)
            Datedifference0  Datedifference1
customerID                                  
1                      10.0             11.0
2                       6.0              NaN

谢谢你的回复。我会查看堆栈文档以了解一些简要信息,但是你的建议出现了KeyError: 'Transaction'错误。我哪里做错了? - miner
@miner - 如果使用customerID而不是Transaction,它会如何工作? - jezrael
有没有一种方法可以在 pandas 中对列进行计算?数据源是一个 CSV 文件,其中包含交易、客户 ID 和日期,因此我可以在单个行中拥有所有交易。但这意味着,我有例如 20 行客户 ID 为 123 的不同交易编号和日期。 - miner
@miner - 不理解,期望的输出结果不同?你能否在问题中编辑期望的输出结果? - jezrael
不,我的问题描述中已经说明了预期输出。但是初始数据源是一个CSV文件,其中包含“Transaction”、“customerId”和“Date”列。样本几乎有20,000行,每个交易对应一行。 - miner
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接