pandas 如何标记连续值而忽略第一个值

wgx48brx  于 2023-02-20  发布在  其他
关注(0)|答案(2)|浏览(149)

下面的代码:

data={'id':[1,2,3,4,5,6,7,8,9,10,11],
  'value':[1,0,1,0,1,1,1,0,0,1,0]}
  df=pd.DataFrame.from_dict(data)
  df
  Out[8]: 
      id  value
 0    1      1
 1    2      0
 2    3      1
 3    4      0
 4    5      1
 5    6      1
 6    7      1
 7    8      0
 8    9      0
 9    10     1
10    11     0

我想创建一个标志列,用从第二次出现开始的1个连续值表示,并忽略第一次出现。
使用实际解决方案:

df['flag'] = 
df.value.groupby([df.value,df.flag.diff().ne(0).cumsum()]).transform('size').ge(3).astype(int)

Out[8]: 
        id  value  flag
    0    1      1     0
    1    2      0     0
    2    3      1     0
    3    4      0     0
    4    5      1     1
    5    6      1     1
    6    7      1     1
    7    8      0     1
    8    9      0     1
    9    10     1     0
   10    11     0     0

虽然我需要这样的解决方案,其中第一个示例从第二个示例开始标记为0和1:

Out[8]: 
        id  value  flag
    0    1      1    0
    1    2      0    0
    2    3      1    0
    3    4      0    0
    4    5      1    0
    5    6      1    1
    6    7      1    1
    7    8      0    0
    8    9      0    1
    9    10     1    0
   10    11     0    0
lskq00tm

lskq00tm1#

通过比较Series.shift与不相等和Series.cumsum的值来创建连续组,通过GroupBy.cumcount创建计数器,并比较0Series.gt之间的较大值,最后通过Series.astype强制转换为整数来将True, FalseMap到1, 0

df['flag'] = (df.groupby(df['value'].ne(df['value'].shift()).cumsum())
                .cumcount()
                .gt(0)
                .astype(int))
print (df)
    id  value  flag
0    1      1     0
1    2      0     0
2    3      1     0
3    4      0     0
4    5      1     0
5    6      1     1
6    7      1     1
7    8      0     0
8    9      0     1
9   10      1     0
10  11      0     0

工作原理:

print (df.assign(g = df['value'].ne(df['value'].shift()).cumsum(),
                 counter = df.groupby(df['value'].ne(df['value'].shift()).cumsum()).cumcount(),
                 mask = df.groupby(df['value'].ne(df['value'].shift()).cumsum()).cumcount().gt(0)))

    id  value  g  counter   mask
0    1      1  1        0  False
1    2      0  2        0  False
2    3      1  3        0  False
3    4      0  4        0  False
4    5      1  5        0  False
5    6      1  5        1   True
6    7      1  5        2   True
7    8      0  6        0  False
8    9      0  6        1   True
9   10      1  7        0  False
10  11      0  8        0  False
yptwkmov

yptwkmov2#

使用groupby.cumcount和自定义grouper:

# group by identical successive values
grp = df['value'].ne(df['value'].shift()).cumsum()

# flag all but the first one (>0)
# convert the booleans True/False to integers 1/0
df['flag'] = df.groupby(grp).cumcount().gt(0).astype(int)

跳过第一个N的通用代码:

N = 1

grp = df['value'].ne(df['value'].shift()).cumsum()
df['flag'] = df.groupby(grp).cumcount().ge(N).astype(int)

输出:

id  value  flag
0    1      1     0
1    2      0     0
2    3      1     0
3    4      0     0
4    5      1     0
5    6      1     1
6    7      1     1
7    8      0     0
8    9      0     1
9   10      1     0
10  11      0     0

相关问题