Группировка данных Pandas на один столбец, падение строк на основе другого столбца

У меня есть dataframe pandas, который выглядит так:

UNIT MACHINE
1 a100 001
2 a100 002
3 a100 003
4 a100 001
5 b222 001
6 b222 002
7 b222 002
8 b222 003

Я хотел бы сгруппировать его на основе "UNIT" и удалить строки, которые не имеют последовательности [001, 002, 003] "MACHINE". Это означает, что из-за того, что UNIT "a100" имеет последовательность [001, 002, 003, 001], его следует отбросить, но UNIT "b222" остается, поскольку последовательность правильная, независимо от повторения MACHINE 002.

Результат должен выглядеть следующим образом:

UNIT MACHINE
5 b222 001
6 b222 002
7 b222 002
8 b222 003

Последовательность [001, 002, 003] является одной из приемлемых последовательностей MACHINE, которые я написал здесь в качестве примера. Есть несколько таких последовательностей, все из которых монотонно возрастают.

Как объединить GroupBy и отказаться от этого?

3 ответа

In [26]: chk_set = set(df.MACHINE.unique())

In [27]: df[df.groupby('UNIT')['MACHINE']
 .transform(lambda x: x.is_monotonic_increasing & chk_set.issubset(set(x)))]
Out[27]:
 UNIT MACHINE
5 b222 001
6 b222 002
7 b222 002
8 b222 003

ОБНОВИТЬ:

если у вас есть следующий DF:

In [90]: df
Out[90]:
 UNIT MACHINE
1 a100 001
2 a100 002
3 a100 003
4 a100 001
5 b222 001
6 b222 002
7 b222 002
8 b222 003
9 c1 001
10 c1 003
11 c2 078
12 c2 079
13 c2 080
14 c3 078
16 c3 080

и массив конкатенированных групп для проверки:

In [91]: chk_groups = np.array(['001002003','078079080'])

Решение:

In [92]: df[df.groupby('UNIT')['MACHINE']
 .transform(lambda x: x.is_monotonic_increasing
 & np.in1d(x.unique().sum(),chk_groups))]
Out[92]:
 UNIT MACHINE
5 b222 001
6 b222 002
7 b222 002
8 b222 003
11 c2 078
12 c2 079
13 c2 080


Ты можешь сделать:

df.groupby('UNIT')['MACHINE'].transform(lambda x : (x.astype(int).diff().fillna(0) >= 0).all()) 
df[sample]

 UNIT MACHINE
5 b222 1
6 b222 2
7 b222 2
8 b222 3


Используйте diff + groupby + transform со all.

m = df.MACHINE\
 .astype(int)\
 .diff()\
 .fillna(0)\
 .isin([0, 1])\
 .groupby(df.UNIT)\
 .transform('all')

m

1 False
2 False
3 False
4 False
5 True
6 True
7 True
8 True
Name: MACHINE, dtype: bool

Используйте diff + isin для определения того, являются ли строки неубывающими или нет (только шаги из 0 или 1 считаются действительными).

Затем, используя m, индекс в df.

df[m]

 UNIT MACHINE
5 b222 001
6 b222 002
7 b222 002
8 b222 003

licensed under cc by-sa 3.0 with attribution.