【问题标题】:First time group meets condition in pandas DataFrame第一次组在 pandas DataFrame 中满足条件
【发布时间】:2021-12-04 01:50:13
【问题描述】:

我有以下pandas.DataFrame

id year x
0 01001 2015 0
1 01001 2016 0.5
2 01001 2017 0
3 01001 2018 0
4 01002 2015 0
5 01002 2016 0
6 01002 2017 0.0667525
7 01002 2018 0.133505

我的目标是创建一个新列,并第一次用1 填充每个窗口x > 0 之后的一行,并用0 填充所有前面的行。那就是:

id year x y
0 01001 2015 0 0
1 01001 2016 0.5 0
2 01001 2017 0 1
3 01001 2018 0 1
4 01002 2015 0 0
5 01002 2016 0 0
6 01002 2017 0.0667525 0
7 01002 2018 0.133505 1

如何做到这一点?

这就是我想出的:第一次获取每个组的索引x > 0,然后用该索引中的1 填充每个窗口,直到分区结束。然后,获取这些索引并将它们的行替换为0

这是我的数据的可复制示例:

t = pd.DataFrame({'id':{0:'01001',1:'01001',2:'01001',3:'01001',4:'01002',5:'01002',6:'01002',7:'01002'},
                  'x':{0:0.0,1:0.5,2:0,3:0,4:0.0,
                        5:0.0,6:0.06675245612859726,7:0.13350491651818122},
                  'year':{0:2015,1:2016,2:2017,3:2018,4:2015,5:2016,6:2017,7:2018}})
t

【问题讨论】:

  • 感谢编辑,您尝试过df['y'] = df.groupby('id', as_index=False).apply(lambda p: (p['x'].shift().gt(0)).astype(int)).droplevel(0, axis=0)吗?
  • 啊!很近!我希望最后一次编辑能更好地展示我的问题。
  • 是的,使用 cumsum,df['y'] = df.groupby('id', as_index=False).apply(lambda p: (p['x'].shift().gt(0)).cumsum()).droplevel(0, axis=0)

标签: python pandas group-by partition-by


【解决方案1】:

有条件地检查连续出现呢?

df['y'] = df.groupby('id', as_index=False).apply(lambda p: (p['x'].shift().gt(0)).cumsum()).droplevel(0, axis=0)



    id  year         x   y
0  1001  2015  0.000000  0
1  1001  2016  0.500000  0
2  1001  2017  0.000000  1
3  1001  2018  0.000000  1
4  1002  2015  0.000000  0
5  1002  2016  0.000000  0
6  1002  2017  0.066753  0
7  1002  2018  0.133505  1

【讨论】:

  • 这其实很聪明。可以id做同样的分组吗?以目前的形式,我认为这不会在组的第一行开始为 >0 时起作用。
  • 你的意思是,df['y'] = df.groupby('id', as_index=False).apply(lambda p: (p['x'].gt(0)&p['x'].shift().gt(0)).astype(int)).droplevel(0, axis=0)
  • 我正在尝试考虑如果组显示以下行为是否可行:0, .5, 0, 0。这就是我试图获取第一次出现的全部原因。无论如何,我认为这解决了我的大部分问题。
  • 为了清晰起见,修改您的输入、输出。 Hower 在我看来,您的最初问题已得到解答:-)
  • 如果我们尝试df['y'] = df.groupby('id', as_index=False).apply(lambda p: (p['x'].shift().gt(0)).astype(int)).droplevel(0, axis=0)会怎样?
【解决方案2】:

让我们试试transform:

df['y'] = (df.index > (df['x']>0).groupby(df['id']).transform('idxmax')).astype(int)
df
      id  year         x  out
 0  1001  2015  0.000000    0
 1  1001  2016  0.500000    0
 2  1001  2017  0.000000    1
 3  1001  2018  0.000000    1
 4  1002  2015  0.000000    0
 5  1002  2016  0.000000    0
 6  1002  2017  0.066753    0
 7  1002  2018  0.133505    1

【讨论】:

  • 嗨,贝尼。你能解释一下transform('idxmax') 的工作原理吗?
  • @ArturoSbr 获取所有groupby每个item的值大于0的第一个位置,然后你可以比较他们的索引~
【解决方案3】:

这是使用cumprod的一种方式

df.groupby('id')['x'].transform(lambda x: (~x.eq(0).shift().cumprod().astype(bool)).astype(int))

【讨论】:

    猜你喜欢
    • 2018-05-16
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2020-01-16
    • 1970-01-01
    相关资源
    最近更新 更多