我有一个如下所示的数据框
df1 = pd.DataFrame({'subject_id' :[1,1,1,1,1,1,1,2,2,2,2],'day':[3,7,9,10,11,19,20,7,13,18,22] , 'fake_flag' :['fake VAC','','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC']})
如下图所示
我想根据以下规则在 actual_flag
列中填写值
a) fake_flag
的值应为 fake_vac
并且不应该为空
b) 仅在 fake_vac
出现时的第一天以及14 天间隔
之后的记录填写值。
这是我尝试过的
t = df1[df1['fake_flag'] == 'fake VAC']
sub_list = t['subject_id'].unique().tolist()
for sub in sub_list:
day_list = t['day'][t['subject_id']==sub].tolist()
min_value = min(day_list)
index = t[t['day']==min_value].index
df1.loc[index, 'actual_flag'] = 'act_vac'
i_14day = min_value + 14
day_values = [i for i in day_list if i >= i_14day]
print("day greater than 14 are ", day_values)
if len(day_values) > 0:
for val in day_values:
index = t[t['day']==val].index
df1.loc[index, 'actual_flag'] = 'act_vac'
正如您所看到的,这非常冗长,我无法对百万条记录的数据集执行此操作。任何高效且优雅的方法都是有帮助的
我期望我的输出如下所示
在本例中,对于 subject_id = 1,第 3 天
是 fake vac
第一次出现,第 19 天
(19 是 gt > 3) 中的 14 天间隔和第 20 天
(20 是 gt > 3 中的 14 天间隔)是在 14 天间隔之后。任何优雅且高效的解决方案都是有帮助的
测试样本数据
df1 = pd.DataFrame({'subject_id' :[1,1,1,1,1,1,1,1,2,2,2,2],'day':[2,3,7,9,10,11,19,20,7,13,18,22] , 'fake_flag' :['','fake VAC','','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC','fake VAC']})
**更新屏幕截图**
最佳答案
一种方法是从每组中的所有日期中减去第一天,检查哪些日期大于 14
并将它们设置为 “act_vac”
,以及最初的日子:
import numpy as np
# Returns a boolean with True if a given day - first day > 14
ix = df1.fake_flag.ne('').groupby(df1.subject_id).transform('idxmax')
c1 = df1.day.sub(df1.values[ix, 1]).gt(14)
# True if the id is different to previous row
c2 = df1.subject_id.ne(df1.subject_id.shift())
# logical OR of the above conditions
df1['actual_flag'] = np.where(c1 | c2, 'act_vac', '')
subject_id day fake_flag actual_flag
0 1 3 fake VAC act_vac
1 1 7
2 1 9 fake VAC
3 1 10 fake VAC
4 1 11 fake VAC
5 1 19 fake VAC act_vac
6 1 20 fake VAC act_vac
7 2 7 fake VAC act_vac
8 2 13 fake VAC
9 2 18 fake VAC
10 2 22 fake VAC act_vac
<小时/>
详细信息
df1.assign(c1=c1, c2=c2, actual_flag= np.where(c1 | c2, 'act_vac', ''))
subject_id day fake_flag actual_flag c1 c2
0 1 3 fake VAC act_vac False True
1 1 7 False False
2 1 9 fake VAC False False
3 1 10 fake VAC False False
4 1 11 fake VAC False False
5 1 19 fake VAC act_vac True False
6 1 20 fake VAC act_vac True False
7 2 7 fake VAC act_vac False True
8 2 13 fake VAC False False
9 2 18 fake VAC False False
10 2 22 fake VAC act_vac True False
关于python - 根据组的天间隔为列分配值的优雅方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57671451/