Значение столбца будет увеличиваться и сбрасываться для изменений в других двух столбцах. - PullRequest
5 голосов
/ 02 августа 2020

У меня есть фрейм данных, в котором я хочу продолжать увеличивать значение до тех пор, пока val не изменится, а когда id изменения не сбросят count значение

data = [['p1',1],
        ['p1',1],
        ['p1',2],
        ['p2',3],
        ['p2',5],
        ['p3',1],
        ['p3',2],
        ['p3',1]]

df = pd.DataFrame(data = data,columns = ['id','val'])

Желаемый результат

       id val  count
    0  p1   1      1
    1  p1   1      1
    2  p1   2      2
    3  p2   3      1
    4  p2   5      2
    5  p3   1      1
    6  p3   2      2
    7  p3   1      3

У меня до сих пор

df['count'] = (df.val.diff() != 0).cumsum()

Это изменяется только при изменении val столбца, но не сбрасывается при id изменении столбца

Ответы [ 4 ]

7 голосов
/ 02 августа 2020

вы можете попробовать groupby+transform с lambda

df['count'] = df.groupby("id")['val'].transform(lambda x: x.ne(x.shift()).cumsum())
print(df)

   id  val  count
0  p1    1      1
1  p1    1      1
2  p1    2      2
3  p2    3      1
4  p2    5      2
5  p3    1      1
6  p3    2      2
7  p3    1      3
5 голосов
/ 02 августа 2020

Решение, основанное на вашей первоначальной попытке:

df['count'] = df.assign(dif = (df.val.diff() != 0)).groupby(['id']).dif.cumsum()

результат:

   id  val  count
0  p1    1    1.0
1  p1    1    1.0
2  p1    2    2.0
3  p2    3    1.0
4  p2    5    2.0
5  p3    1    1.0
6  p3    2    2.0
7  p3    1    3.0

С учетом комментариев @ALollz, альтернативное решение:

df['count'] = df.assign(dif = (df.val.diff() != 0).astype(int)).groupby(['id']).dif.apply(lambda x : x.cumsum().rank(method='dense'))

Теперь в группах подсчет всегда начинается с 1.

2 голосов
/ 02 августа 2020

сделаю

df.val.diff().ne(0).cumsum().groupby(df.id).transform(lambda x : x.factorize()[0]+1)
Out[149]: 
0    1
1    1
2    2
3    1
4    2
5    1
6    2
7    3
Name: val, dtype: int32
1 голос
/ 02 августа 2020
df2 = df.groupby(['id','val']).size().reset_index() #get unique combinations
df2 = df2.groupby('id').val.cumcount()

Подробнее о cumcount в docs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...