【问题标题】:Compare preceding two rows with subsequent two rows of each group till last record将每组的前两行与后两行进行比较,直到最后一条记录
【发布时间】:2019-12-31 07:39:30
【问题描述】:

我之前有一个问题已被删除,现在修改为不那么冗长的形式,以便您轻松阅读。

我有一个如下所示的数据框

df = pd.DataFrame({'subject_id' :[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],'day':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] , 'PEEP' :[7,5,10,10,11,11,14,14,17,17,21,21,23,23,25,25,22,20,26,26,5,7,8,8,9,9,13,13,15,15,12,12,15,15,19,19,19,22,22,15]})
df['fake_flag'] = ''

我想根据以下规则填写fake_flag 列中的值

1) 如果前两行是常数(例如:5,5)或递减(7,5),则选择两行中最高的一行。在这种情况下,它是 (7,5) 中的 7 和 (5,5) 中的 5

2) 检查当前行是否比规则 1 的输出大 3 点或更多点 (>=3) 并在另一(下)行中重复(出现 2 次相同值)。它可以是 8/gt 8(如果规则 1 输出为 5)。例如:(n 行中的 8 个,n+1 行中的 8 个或 n 行中的 10 个,n+1 行中的 10 个)如果是,则在 fake_flag column 中键入 fake VAC

这是我尝试过的

for i in t1.index:
if i >=2:
    print("current value is  ", t1[i])
    print("preceding 1st (n-1) ", t1[i-1])
    print("preceding 2nd (n-2) ", t1[i-2])
    if (t1[i-1] == t1[i-2] or t1[i-2] >= t1[i-1]): # rule 1 check
        r1_output = t1[i-2] # we get the max of these two values (t1[i-2]), it doesn't matter when it's constant(t1[i-2] or t1[i-1]) will have the same value anyway
        print("rule 1 output is ", r1_output)
        if t1[i] >= r1_output + 3:
            print("found a value for rule 2", t1[i])
            print("check for next value is same as current value", t1[i+1])
            if (t1[i]==t1[i+1]): # rule 2 check
                print("fake flag is being set")
                df['fake_flag'][i] = 'fake_vac'

应该对每个 subject_id 的所有记录(一个接一个)进行此检查。我有一个包含数百万条记录的数据集。任何有效而优雅的解决方案都是有帮助的。我无法运行超过百万条记录的循环。

我希望我的输出如下所示

subject_id = 1

subject_id = 2

【问题讨论】:

  • 我们试一试
  • 如果您对理解逻辑有任何疑问,请告诉我。
  • 是的,我明白了。虽然不是一件容易的事:-)
  • 抱歉,矢量化真的很难,现在没有时间,我会再试一试。希望你能解决

标签: python python-3.x pandas dataframe pandas-groupby


【解决方案1】:
import pandas as pd
df = pd.DataFrame({'subject_id' :[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],'day':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] , 'PEEP' :[7,5,10,10,11,11,14,14,17,17,21,21,23,23,25,25,22,20,26,26,5,7,8,8,9,9,13,13,15,15,12,12,15,15,19,19,19,22,22,15]})

df['shift1']=df['PEEP'].shift(1)
df['shift2']=df['PEEP'].shift(2)

df['fake_flag'] = np.where((df['shift1'] ==df['shift2']) | (df['shift1'] < df['shift2']), 'fake VAC', '')
df.drop(['shift1','shift2'],axis=1)

输出

0   1   1   7   
1   1   2   5   
2   1   3   10  fake VAC
3   1   4   10  
4   1   5   11  fake VAC
5   1   6   11  
6   1   7   14  fake VAC
7   1   8   14  
8   1   9   17  fake VAC
9   1   10  17  
10  1   11  21  fake VAC
11  1   12  21  
12  1   13  23  fake VAC
13  1   14  23  
14  1   15  25  fake VAC
15  1   16  25  
16  1   17  22  fake VAC
17  1   18  20  fake VAC
18  1   19  26  fake VAC
19  1   20  26  
20  2   1   5   fake VAC
21  2   2   7   fake VAC
22  2   3   8   
23  2   4   8   
24  2   5   9   fake VAC
25  2   6   9   
26  2   7   13  fake VAC

【讨论】:

  • 您好,感谢您的回复。但正如您所看到的,它与预期的输出不匹配。尽管如此,还是为您的帮助而投票
  • 我猜你错过了 3 分 (>= 3) 的条件来获得fake vac 的资格。
  • @SSMK 我希望您至少了解如何将规则 3 添加到此解决方案中。希望答案有帮助。所以请接受。我没有清楚地理解规则 3。
  • 为了对其他人有用,您介意更新您的答案吗?
  • 规则 2 对您来说不是很清楚吗?要我再解释一遍吗?输出屏幕截图没有帮助吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 2012-02-24
  • 2021-12-21
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多