我想通过任意过程从pandas数据集创建新特征



当前正在使用以下数据集。

import pandas as pd
import io
csv_data = '''
ID,age,get_sick,year
4567,76,0,2014
4567,78,0,2016
4567,79,1,2017
12168,65,0,2014
12168,68,0,2017
12168,69,0,2018
12168,70,1,2019
20268,65,0,2014
20268,66,0,2015
20268,67,0,2016
20268,68,0,2017
20268,69,1,2018
22818,65,0,2008
22818,73,1,2016
'''
df = pd.read_csv(io.StringIO(csv_data), index_col=['ID', 'age'])
get_sick  year
ID    age                
4567  76          0  2014
78          0  2016
79          1  2017
12168 65          0  2014
68          0  2017
69          0  2018
70          1  2019
20268 65          0  2014
66          1  2015
67          1  2016
68          1  2017
69          1  2018
22818 65          0  2008
73          1  2016

对于每个人来说,如果体检时的年龄、所测年份以及曾经患过疾病,则get_sick为1。

我们现在正试图建立一个模型来预测一个患有get_sick=0的人将来患上某种疾病的可能性。

我们要检查get_sick=0的人是否在5年内从0变为1,如果是,我们希望在新列'history'中存储1,如果0变为0,我们希望存储0。

我们只针对get_sick=0的数据,因为get_sick=1的数据不用于训练。

尝试
N = 3
idx = df.groupby('ID').apply(lambda x: x.query("(year - @x.year.min()) <= @N")['get_sick'].max())
df_1 = df.reset_index().assign(history=df.reset_index()['ID'].map(idx)).set_index(['ID', 'age'])
df_1

这个过程并没有给我们理想的治疗,因为我们只比较了第一年。

理想的输出结果如下

get_sick  year  history
ID    age                
4567  76          0  2014       1
78          0  2016       1
79          1  2017     Nan
12168 65          0  2014       1
68          0  2017       1
69          0  2018       1
70          1  2019     Nan
20268 65          0  2014       1
66          1  2015     Nan
67          1  2016     Nan
68          1  2017     Nan
69          1  2018     Nan
22818 65          0  2008       0
73          1  2016     Nan

如果有人熟悉熊猫的操作,请告诉我,我将不胜感激。

提前谢谢你。

※对于某些数据帧,得到以下结果:

import pandas as pd
import io
csv_data = '''
ID,age,get_sick,year
33868,76,0,2014
33868,78,1,2016
33868,79,1,2017
33868,80,1,2018
'''
df_1 = pd.read_csv(io.StringIO(csv_data), index_col=['ID', 'age'])
get_sick  year  
ID     age                 
33868  76          0  2014       
78          1  2016       
79          1  2017 
80          1  2018

df_mer_1 = df_1[df_1.get_sick == 1].reset_index()[['ID', 'year']]
df_1 = df_1.reset_index().merge(df_mer_1, on = 'ID', suffixes=('', '_max'))
df_1.loc[(df_1.get_sick == 0) & (df_1.year_max - df_1.year <= 5), 'history'] = 1
df_1.loc[(df_1.get_sick == 0) & (df_1.year_max - df_1.year > 5), 'history'] = 0
df_1 = df_1.set_index(['ID', 'age']).drop(columns='year_max')

结果如下

get_sick  year  history
ID     age                
33868  76          0  2014       1
76          0  2014       1
76          0  2014       1 
78          1  2016     Nan
78          1  2016     Nan
78          1  2016     Nan
79          1  2017     Nan
79          1  2017     Nan
79          1  2017     Nan
80          1  2018     Nan
80          1  2018     Nan
80          1  2018     Nan

你知道为什么以这种方式生成多个相同的行吗?如果你能帮助我,我会很高兴的。提前谢谢你。

首先,我创建了一个列,其中包含get_sick = 1的年份。

df_mer = df[df.get_sick == 1].reset_index()[['ID', 'year']].drop_duplicates(subset = 'ID')
df = df.reset_index().merge(df_mer, on = 'ID', suffixes=('', '_max'))

然后可以使用year_max计算年差并分配1/0。

df.loc[(df.get_sick == 0) & (df.year_max - df.year <= 5), 'history'] = 1
df.loc[(df.get_sick == 0) & (df.year_max - df.year > 5), 'history'] = 0
df = df.set_index(['ID', 'age']).drop(columns='year_max')

输出:

get_sick  year  history
ID    age                         
4567  76          0  2014      1.0
78          0  2016      1.0
79          1  2017      NaN
12168 65          0  2014      1.0
68          0  2017      1.0
69          0  2018      1.0
70          1  2019      NaN
20268 65          0  2014      1.0
66          0  2015      1.0
67          0  2016      1.0
68          0  2017      1.0
69          1  2018      NaN
22818 65          0  2008      0.0
73          1  2016      NaN