繁体   English   中英

使用熊猫计算数据框中同一列中多个客户端的同比变化

[英]Computing yoy changes for multiple clients in same column in dataframe using pandas

我有一个包含四列的数据框:

  • 客户编号
  • 日期
  • 资产
  • 流动

并非所有客户都有完整日期集的数据。 在这种情况下,行会丢失。 换句话说,我没有为每个客户提供相同数量的行。

我想计算以下内容并添加其他列:

  • 超过 12m 和 3m 的资产的绝对和相对变化
  • 超过 12m 和 3m 的流量总和

当无法计算统计信息时(即前 11m),该列应使用 nan 填充。

我已经尝试过使用 group,但是无法找到解决每个客户端的数据长度不同这一事实的方法。

这是我的数据(前 4 列)和希望结果(最后 4 列)的示例,在 Excel 中完成:在此处输入图像描述

如果您对每月更改感兴趣,您可以添加列“months_since”,这将等于自某个日期以来的月数。

df.pivot("months_since", "Client ID", "Assets")

获取数据的矩阵表示。 如果某个客户缺少观察,他将有一个 nan 值。

然后很容易使用 df.rolling(12).sum() 或 df.diff(12) 计算总和/增量

import pandas as pd
df_data = pd.read_excel('sample2.xlsx')

df_result_change_assets_3m = df_data.pivot_table(values = 'Assets', index = ['Client ID','Date']).unstack(['Client ID']).pct_change(3).unstack(['Date'])['Assets'].reset_index().rename(columns = {0:'Change Assets 3m (%)'})

df_result_change_assets_12m = df_data.pivot_table(values = 'Assets', index = ['Client ID','Date']).unstack(['Client ID']).pct_change(12).unstack(['Date'])['Assets'].reset_index().rename(columns = {0:'Change Assets 12m (%)'})

df_result_change_usd_assets_3m = df_data.pivot_table(values = 'Assets', index = ['Client ID','Date']).unstack(['Client ID'])
df_result_change_usd_assets_3m = df_result_change_usd_assets_3m - df_result_change_usd_assets_3m.shift(3)
df_result_change_usd_assets_3m = df_result_change_usd_assets_3m.unstack(['Date'])['Assets'].reset_index().rename(columns = {0:'Change Assets 3m (USD)'})

df_result_change_usd_assets_12m = df_data.pivot_table(values = 'Assets', index = ['Client ID','Date']).unstack(['Client ID'])
df_result_change_usd_assets_12m = df_result_change_usd_assets_12m - df_result_change_usd_assets_12m.shift(12)
df_result_change_usd_assets_12m = df_result_change_usd_assets_12m.unstack(['Date'])['Assets'].reset_index().rename(columns = {0:'Change Assets 12m (USD)'})


df_data = df_data.merge(df_result_change_assets_3m, how = 'left', on = ['Client ID','Date'])
df_data = df_data.merge(df_result_change_assets_12m, how = 'left', on = ['Client ID','Date'])
df_data = df_data.merge(df_result_change_usd_assets_3m, how = 'left', on = ['Client ID','Date'])
df_data = df_data.merge(df_result_change_usd_assets_12m, how = 'left', on = ['Client ID','Date'])

df_data

我建议你把问题分成两部分:首先你计算资产的同比增长,然后你可以专注于流量。 对于第一个任务,您可以创建两个新列以使用自联接合并数据。 您可以使用pd.tseries.offsets.MonthEnd方法创建新列,如下所示:

data_df['date_12MonthsAfter'] = data_df['date'] + pd.tseries.offsets.MonthEnd(12)
data_df['date_3MonthsAfter'] = data_df['date'] + pd.tseries.offsets.MonthEnd(3)

您可以将数据与计算所需数量的两个自联接合并。 有几种方法可以做到这一点,我是这样做的:

data_merged_12Months = (data_df.merge(data_df[['clientId', 'date_12MonthsAfter', 'assets']], 
                                  left_on = ['clientId', 'date'], 
                                  right_on = ['clientId', 'date_12MonthsAfter'],
                                  how = 'left', 
                                  suffixes=['', '_prevYear'])).drop(['date_12MonthsAfter',
                                                                     'date_3MonthsAfter',
                                                                     'date_12MonthsAfter_prevYear'], axis = 1)
data_merged_3Months = (data_df.merge(data_df[['clientId', 'date_3MonthsAfter', 'assets']], 
                                 left_on = ['clientId', 'date'], 
                                 right_on = ['clientId', 'date_3MonthsAfter'],
                                 how = 'left', 
                                 suffixes=['', '_prevQuarter'])).drop(['assets',
                                                                       'flow',
                                                                       'date_12MonthsAfter',
                                                                       'date_3MonthsAfter',
                                                                       'date_3MonthsAfter_prevQuarter'], axis = 1)
data_merged_assets = data_merged_12Months.merge(data_merged_3Months, on = ['clientId', 'date'])
data_merged_assets['perc yoy'] = (data_merged_assets['assets'] - data_merged_assets['assets_prevYear'])/data_merged_assets['assets_prevYear']
data_merged_assets['perc qoq'] = (data_merged_assets['assets'] - data_merged_assets['assets_prevQuarter'])/data_merged_assets['assets_prevQuarter']

对于流量计算,您必须用零替换黑色单元格,您可以使用方法.str.replce('', '0')进行计算,并且必须转换int中的列数据类型。 为了计算过去 12 个月和 3 个月的总和,我找到了这个解决方案

data_merged_assets['flow'] = (data_merged_assets.str.replace('', '0')).astype(int)
data_flow_12Months = data_merged_assets.groupby(['clientId']).rolling(on = 'date', window=12, min_periods=12)["flow"].sum().reset_index()
data_flow_3Months = data_merged_assets.groupby(['clientId']).rolling(on = 'date', window=3, min_periods=3)["flow"].sum().reset_index()
data_flow = data_flow_12Months.merge(data_flow_3Months, on = ['clientId', 'date'], suffixes = ['_sumLast12Months', '_sumLast3Months'])

最后,我合并了两个数据集。

data_merged = data_merged_assets.merge(data_flow, on = ['clientId', 'date'])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM