0

在此处输入图像描述

大家好,我想使用 ID、月份和值来计算序列和标志。对于每个唯一的 id,如果值更改为零,则序列为 1,如果连续几个月继续为零,则序列将添加,如上所示。

当序列加到 6 时,标志将为 1。

请帮助我想用 Pandas 和 R 来做

4

2 回答 2

0

R中,我们可以使用 来创建“序列”和“标志” data.table。将 'data.frame' 转换为 'data.table' ( setDT(df1)),按 'Id' 分组,我们用 指定 'i' ,根据 'i' 中的 TRUE 值Value == 0创建 'Sequence' 作为序列 ( )。然后,通过为那些为“序列”为 1 的元素1:.N分配 ( ) 1 来创建“标志”。:=如果有没有 1 的 'Id' 或all'Flag' 值为 NA,则在顶部连接 0,同时从 'Flag' ( Flag[-1]) 中删除一个元素或else返回 'Flag'

library(data.table)
setDT(df1)[Value == 0, Sequence := 1:.N , by = Id]
df1[Sequence ==1, Flag := 1][, Flag := if(all(is.na(Flag))) 
                     c(0, Flag[-1]) else Flag, by = Id]
df1
#        Id  Month Value Sequence Flag
# 1: SCSR1 Jan-16   400       NA   NA
# 2: SCSR1 Feb-16     0        1    1
# 3: SCSR1 Mar-16     0        2   NA
# 4: SCSR1 Apr-16     0        3   NA
# 5: SCSR1 May-16     0        4   NA
# 6: SCSR1 Jun-16     0        5   NA
# 7: SCSR1 Jul-16     0        6   NA
# 8: SCCS9 Jan-16   440       NA    0
# 9: SCCS9 Feb-16  3000       NA   NA
#10: SCCS9 Mar-16   400       NA   NA
#11: SCCS9 Apr-16   100       NA   NA
#12: SCCS9 May-16   300       NA   NA
#13: SCCS9 Jun-16   400       NA   NA
#14: SCCS9 Jul-16   100       NA   NA
#15: SKHH1 Jan-16  1000       NA   NA
#16: SKHH1 Feb-16     0        1    1
#17: SKHH1 Mar-16     0        2   NA
#18: SKHH1 Apr-16     0        3   NA
#19: SKHH1 May-16     0        4   NA
#20: SKHH1 Jun-16     0        5   NA
#21: SKHH1 Jul-16     0        6   NA

注意:最好将 NA 作为缺失值而不是空格 ( "") 以保留列的类别。

数据

df1 <- data.frame(Id = rep(c("SCSR1", "SCCS9", "SKHH1"), each = 7),
    Month = rep(c('Jan-16', 'Feb-16', 'Mar-16', 'Apr-16', 'May-16', 'Jun-16',
   'Jul-16'), 3), Value = c(400, rep(0, 6), 440, 3000, 400, 100, 300, 400,
   100, 1000, rep(0,6)))
于 2016-11-05T14:03:12.717 回答
0

熊猫解决方案如下。

请注意,如果值在 Id 内切换回非零,则下面的序列列将通过复制最后一个值(例如,1、2、3、4、5、6、6、6、6、...)来反映这一点。这可以通过移动 Value 列来清理,就像我们移动 Id 列并在 Id 内进行比较一样。但是,如果值可以在 Id 内的 0 和非零之间波动,那么累积和方法就会失效。如果没有发生这种情况,这种方法应该没问题。我很好奇是否有其他解决方案可以解决这个问题。

import pandas as pd

df = pd.DataFrame({'Id':['SCSR1']*7+['SCCS9']*7+['SKHH1']*7, 'Value':[400]+[0]*6+[440,3000,400,100,300,400,100,1000]+[0]*6})
df['flag'] = 0

# create a shifted column to ensure that comparisons are made within an Id
df['Id2'] = df['Id'].shift()

# set the appropriate flag values to 1 and define the sequences
df.loc[(df['Id'] == df['Id2']) & (df['Value'] == 0), 'flag'] = 1
df['Sequence'] = df.groupby('Id')['flag'].cumsum()

@akrun 已经为您提供了一个漂亮的 R 解决方案。另一种方法是使用 rleid 函数。但我更喜欢@akrun 的解决方案。

于 2016-11-05T14:41:49.173 回答