Группировать только те значения, которые LIKE '[список из 3 значений]'

У меня есть фреймворк pandas. Я хочу выбрать значения из col1, которые должны иметь все 3 значения в col2. col2_values_should start_with = [P1.adv, P2.cmp, P3.part ] Кроме того, поскольку вы можете видеть более позднюю часть значений в col2, это фиктивная часть. поэтому мне нужно использовать такую ​​же опцию, как оператор LIKE SQL, чтобы проверить значения col2.

Группировать только те значения, которые LIKE '[список из 3 значений]'

поэтому ответ из приведенной выше таблицы:

Группировать только те значения, которые LIKE '[список из 3 значений]'

потому что "A" имеет все три требуемые значения, в отличие от B и C.

Итак, в основном я хочу проверить, какое значение в col1 имеет все 3 требуемые значения в col2. и эти значения col2 должны начинаться с определенных букв, как указано выше.

Редактировать:

Пример данных

ID col1 col2

1 A P1.adv abcd

2 А P2.cmp mkmfwk

3 A P3.part lpwf

4 Б P1.adv abcd

5 Б P2.cmp mkmfwk

6 C P1.addv abcd

7 C P1.adv abcd

предоставьте образцы данных в текстовом формате, иначе вам будет сложнее помочь

Yuca 18.12.2018 15:09
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
80
4

Ответы 4

Используйте extract с регулярным выражением с ^ для сопоставления начала строки и | для OR, затем groupby с transform и сравните sets, также сравнивает, если такая же длина групп, как list:

L = ["P1.adv", "P2.cmp", "P3.part"]

pat = '|'.join(r"^{}".format(x) for x in L)
s = df['col2'].str.extract('('+ pat + ')', expand=False)

df = df[s.groupby(df['col1']).transform(lambda x: set(x) == set(L) and len(x) == len(L))]
print (df)
   ID col1           col2
0   1    A    P1.adv abcd
1   2    A  P2.cmp mkmfwk
2   3    A   P3.part 1pwf

Другое решение - фильтрация по startswith, затем агрегирование с size для подсчетов, получение количества уникальных значений по nunique и сравнение обоих по длине списка, последний фильтр по boolean indexing с all для проверки, являются ли оба значения True:

df = df[df['col2'].str.startswith(tuple(L))].copy()
m = df.groupby('col1')['col2'].agg(['size','nunique']) == len(L)
df = df[df['col1'].isin(m.index[np.all(m, axis=1)])]
print (df)
   ID col1           col2
0   1    A    P1.adv abcd
1   2    A  P2.cmp mkmfwk
2   3    A   P3.part 1pwf

Я не думаю, что OP хочет этого

Yuca 18.12.2018 15:13

@jezrael - это не повторяющийся вопрос. Мне нужно ограничить, если col1 имеет определенные значения в col2 (не каждое значение в col2)

Akhan 18.12.2018 15:18

Во втором решении я получаю ошибку памяти. Однако в вашем 1-м решении не могли бы вы сказать, нет ли скобок?

Akhan 18.12.2018 15:42

@frozenshine - у меня все работает нормально, у вас есть синтаксическая ошибка?

jezrael 18.12.2018 15:43

@frozenshine - добавлено альтернативное решение, надеюсь без ошибок памяти.

jezrael 18.12.2018 15:54

Я бы предложил использовать регулярное выражение и подсчитывать количество случаев, когда A равняется [шаблону соответствует

import pandas as pd
df = pd.DataFrame({'a':[1,2,1,1,5,5],'b':["abc.more","abcde.kef","abc.mop","lop.e","lop.e","get.le"]})
con = df.b.str.match('^(abc.m|lop.e)')
df['c'] = con
df['sum_c'] = df.groupby('a')['c'].transform('sum')
df['count_a'] = df.groupby('a')['a'].transform('count')
dff = df[df['count_a']==df['sum_c']]
dff

Вот как это сделать:

l = ('P1.adv', 'P2.cmp', 'P3.part' )
m1 = df.groupby('col1').apply(lambda x: x.col2.str.startswith(l, na=False)).reset_index()
m2 = df[m1.col2].groupby('col1').col2.nunique() > 2
df[df.col1.isin(m2[m2].index.values)]

   ID  col1         col2
0   1    A   P1.adv abcd
1   2    A  P2.cmp kmasd
2   3    A   P3.part lpw

Объяснение

Вы можете начать с проверки, какие строки в df содержат col2, который начинается с одного из элементов в списке, используя str.startswith.

print(m1)

 col1  level_1  col2
0    A        0  True
1    A        1  True
2    A        2  True
3    B        3  True
4    B        4  True
5    C        5  True
6    C        6  True

После того, как вы можете сгруппировать по col1 и проверить, что количество уникальных элементов больше 2 (это означает, что каждый из элементов в списке присутствует хотя бы один раз) с помощью GroupBy.nunique():

print(m2)

col1
A     True
B    False
C    False
Name: col2, dtype: bool

и, наконец, используйте логическую индексацию на исходном df с помощью m2:

result = df[df.col1.isin(m2[m2].index.values)]
print(result)

    ID  col1        col2
0   1    A   P1.adv abcd
1   2    A  P2.cmp kmasd
2   3    A   P3.part lpw

Создайте временный столбец в фрейме данных, который проверяет, присутствует ли какой-либо целевой префикс в col2. Затем сгруппируйте их по столбцу 1 и сумме. Затем проверьте, равна ли сумма 3

ans = (df.assign(temp = df.col2.str.startswith(tuple(col2_values_should_start_with)))\
         .groupby('col1')[['temp']].sum() == 3).reset_index()

Наконец, найдите значение col1, которое имеет 3 начальные строки

df[df['col1'].isin(list(ans[ans.temp == True].col1))]

Вывод:

    ID   col1       col2
    1    A    P1.advabcd
    2    A  P2.cmpmkmfwk
    3    A   P3.partlpwf

Другие вопросы по теме