我有一个数据框,该数据框由混淆矩阵分组(tp,fp,fn,tn),模型名称(下面的示例有2个模型,但实际上这是一个可变量并且要大得多)和比例(给定模型中的示例比例+混淆矩阵分组,例如,模型1的示例比例为tp)。数据框看起来像这样,但它又组成了并且要小得多。
confusion_matrix_group | model | proportion
TP Model1 0.73
TN Model1 0.27
FN Model2 0.24
TP Model2 0.58
TN Model2 0.18
...
如您所见,给定模型的TP + FP + FN + TN比例总和为1。但是,如示例中所示,模型可能没有全部4个分组(model1和FN仅TP / TN / TP / TN(型号2)。我想遍历并填写所有缺少的组,以进行分组,模型化,并为比例添加0.0。上面的示例将变成这样:
confusion_matrix_group | model | proportion
TP Model1 0.73
TN Model1 0.27
FN Model2 0.24
TP Model2 0.58
TN Model2 0.18
FP Model1 0.0
FN Model1 0.0
FP Model2 0.0
...
我尝试应用以下代码,但是由于某些原因,它没有进入下面的if条件,这对我来说没有意义。我怀疑这是解决此问题的最佳方法,因此完全可以修复此代码或其他建议。感谢您的帮助!
for group in ['TP', 'TN', 'FP', 'FN']: for model in np.unique(df.model): print([group, model]) # To fix: This condition doesn't work if [group, model]) not in df[['confusion_matrix_group', 'model']].values: # TODO: ADD NEW ROW to df
答案 0 :(得分:2)
一种方法是先残酷地添加所有组合,然后再残酷地添加drop_duplicates
(可能对性能不利):
import pandas as pd
df = pd.DataFrame({'confusion_matrix_group': {0: 'TP', 1: 'TN', 2: 'FN', 3: 'TP', 4: 'TN'},
'model': {0: 'Model1', 1: 'Model1', 2: 'Model2', 3: 'Model2', 4: 'Model2'},
'proportion': {0: 0.73, 1: 0.27, 2: 0.24, 3: 0.58, 4: 0.18}})
df2 = pd.DataFrame([[x, i, 0] for i in df["model"].unique() for x in ("TP","FP","FN","TN")],columns=df.columns)
print (pd.concat([df,df2],ignore_index=True).drop_duplicates(["model","confusion_matrix_group"],keep="first"))
#
confusion_matrix_group model proportion
0 TP Model1 0.73
1 TN Model1 0.27
2 FN Model2 0.24
3 TP Model2 0.58
4 TN Model2 0.18
6 FP Model1 0.00
7 FN Model1 0.00
10 FP Model2 0.00
另一种类似的方式,首先创建一个串联名称的新列:
df["new"] = df["confusion_matrix_group"]+df["model"]
df2 = pd.DataFrame([[x, i, 0, x+i] for i in df["model"].unique() for x in ("TP","FP","FN","TN")],columns=df.columns)
print (pd.concat([df,df2.loc[~df2["new"].isin(df["new"])]],ignore_index=True))
#
confusion_matrix_group model proportion new
0 TP Model1 0.73 TPModel1
1 TN Model1 0.27 TNModel1
2 FN Model2 0.24 FNModel2
3 TP Model2 0.58 TPModel2
4 TN Model2 0.18 TNModel2
5 FP Model1 0.00 FPModel1
6 FN Model1 0.00 FNModel1
7 FP Model2 0.00 FPModel2
答案 1 :(得分:1)
您可以使用此:
names = ['confusion_matrix_group','model']
mind = pd.MultiIndex.from_product([['TP', 'TN', 'FP', 'FN'], df['model'].unique()], names=names)
df.set_index(names).reindex(mind, fill_value=0).reset_index()
df
confusion_matrix_group model proportion
0 TP Model1 0.73
1 TP Model2 0.58
2 TN Model1 0.27
3 TN Model2 0.18
4 FP Model1 0.00
5 FP Model2 0.00
6 FN Model1 0.00
7 FN Model2 0.24
答案 2 :(得分:0)
尝试一下:
for group in ['TP', 'TN', 'FP', 'FN']:
for model in np.unique(df.model):
if [group, model] not in df[['confusion_matrix_group', 'model']].values.tolist():
df=df.append(pd.Series({'confusion_matrix_group': group, 'model': model, 'proportion': 0}),ignore_index=True)
输出:
confusion_matrix_group model proportion
0 TP Model1 0.73
1 TN Model1 0.27
2 FN Model2 0.24
3 TP Model2 0.58
4 TN Model2 0.18
5 FP Model1 0
6 FP Model2 0
7 FN Model1 0
答案 3 :(得分:0)
这是不使用df.groupby
和apply
的double for循环的解决方案:
def fill_models(grp):
possible = ['TP', 'FP', 'TN', 'FN']
model = grp['model']
values = grp['confusion_matrix_group']
if values.shape[0] < 4:
grp = grp.append(pd.DataFrame([[group, model, 0.0] for group in possible if group not in values.values], columns=grp.columns))missing], columns=grp.columns))
return grp
df_full = df.groupby('model')[df.columns].apply(fill_models).reset_index(drop=True)
优点是不检查已存在的任何分组,并且应该运行得很快,尽管我没有对其进行计时
答案 4 :(得分:0)
一种解决方案是使用groupby查找每个模型的缺失组,并将其附加到df
groups = ['TP', 'TN', 'FP', 'FN']
models = df['model'].unique()
df2 = df.groupby(['model']).apply(lambda x: list(set(groups) - set(x['confusion_matrix_group']))).explode()
df2 = pd.DataFrame(df2).reset_index(level=0).rename(columns={0:'confusion_matrix_group'})
df2['proportion'] = 0
df.append(df2, sort=False)
它将给出以下输出
confusion_matrix_group model proportion
0 TP Model1 0.73
1 TN Model1 0.27
2 FN Model2 0.24
3 TP Model2 0.58
4 TN Model2 0.18
0 FP Model1 0.00
1 FN Model1 0.00
2 FP Model2 0.00
答案 5 :(得分:0)
在这种情况下,我认为对数据框进行排序是一种好习惯。它有助于区分丢失的数据并简化应用 在整个数据框结构中发生变化。
df = df.sort_values(by=['model','confusion_matrix_group'])
group = ['FN','FP','TN','TP'] #group options
row = []
for c in list(df.groupby('model')['confusion_matrix_group']): #group by model
if c[0]:
y = list(set(group) - set(c[1])) #elements in group list not in confusion_matrix...
for val in y:
data = [c[0],val,0.0]
row.append(data)
#new matrix to append
dnew = pd.DataFrame(row,columns=['confusion_matrix_group','model','proportion'])
df = (df.append(dnew,ignore_index=False)).sort_values(by=['model','confusion_matrix_group'])
print(df)
confusion_matrix_group model proportion
0 FN Model1 0.00
1 FP Model1 0.00
1 TN Model1 0.27
0 TP Model1 0.73
2 FN Model2 0.24
2 FP Model2 0.00
4 TN Model2 0.18
3 TP Model2 0.58