背景
从事风控工作,经常要统计风险等级这个标签,也可能需要统计不同风险等级在不同平台下的频率,也就是出现次数,以此来作为策略有效性评估的一个指标。
一个常见的场景是:当你需要作图的时候,发现某一天,或者一直以来都没有某一个风险等级,这种情况下作图也好,作表也好,都会出现一个断层。
比如画出来的图形是这个样子的:
数据是我随机生成的,想表达的一点就是:
WEB端有3条线,但是APP端只有2条蓝色的线,APP端少了一个risklevel为1的数据。
问题提出
其实,这个在经济学中较面板数据,无论在做回归分析还是建模的时候,一般都需要补成一个long型的数据。
这个数据,就是类似下面这种形式。year,variablename,value
我们要做的就是,将缺失的风险等级给他补上。
解决方案
一个根据dataframe进行补0的方案函数
注意点
- 数据里面,删除掉你不需要的列,保留你需要的列就行
import pandas as pd
from itertools import product
def expand_dataframe(df, expand_cols):
# 第一步,找出去重后的唯一值
unique_values = [df[col].unique() for col in expand_cols]
# 第二步,创建组合dataframe
all_combinations = pd.DataFrame(list(product(*unique_values)), columns=expand_cols)
# 第三步,与原始数据合并
expanded_df = pd.merge(all_combinations, df, on=expand_cols, how='left')
# 第四步,补值
expanded_df.fillna(0,inplace=True)
return expanded_df
生成数据的代码和其他信息
import pandas as pd
import numpy as np
# 生成1个星期的日期变量
dates = pd.date_range(start='2023-12-01', periods=7)
# 生成作图dataframe
# 生成风险等级为1,2,3,且channel 为APP或者WEB的数据,并且channel为APP且风险等级为1的数据不生成
data = []
for date in dates:
for risk_level in [1,2, 3]:
for channel in ['APP', 'WEB']:
if risk_level == 1 and channel=='APP':
continue
num = np.random.randint(10, 90)
data.append([date, risk_level, num, channel])
# 生成df
df = pd.DataFrame(data, columns=['date', 'risklevel', 'num', 'channel'])
df的前10行数据如下:
作图的代码
import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use('ggplot')
plt.figure()
sns.lineplot(data=df,x='date',y='num',hue='channel',style='risklevel',markers=True,dashes=False,linewidth=2.5)
plt.show()