Флаг, если последний элемент в группе содержит определенную строку в Pandas - PullRequest
0 голосов
/ 28 января 2019

У меня есть данные:

Group   string
 A     Hello
 A     SearchListing
 A     GoSearch
 A     pen
 A     Hello
 A     Searches
 B     Real-Estate
 B     Access
 B     Denied
 B     Group
 B     Group
 C     Glance
 C     NoSearch
 C     Home
 C     FullSearch

и т. Д.

Я хочу найти группу, в которой строка «поиск» является последним элементом, и пометить их.Например, вывод, который я хочу, выглядит примерно так:

  Group   Flag
   A       1
   B       0
   C       1

, так как у A и C был последний элемент, содержащий строку «search».Я знаю метод, который может перебирать все элементы, и если последний элемент содержит «поиск», он помечает его.Но это очень тяжелая функция с использованием циклов.Есть ли более прямой путь для этого?

Ответы [ 4 ]

0 голосов
/ 29 января 2019

Это также работает:

df.groupby('Group')['string'].apply(lambda x: 'search' in x.str.cat().lower()).reset_index(name='Flag')

Вывод:

Group   Flag
0   A   True
1   B   False
2   C   True

Сравнение скорости

%%timeit
df.drop_duplicates('Group',keep='last').\
           assign(Flag=lambda x : x['string'].str.contains('Search'))
# 1000 loops, best of 3: 1.1 ms per loop

%%timeit
df.groupby("Group")["string"] \
  .apply(lambda x: int("search" in x.values[-1].lower())) \
  .reset_index(name="Flag")
# 1000 loops, best of 3: 1.6 ms per loop

%timeit df.groupby('Group')['string'].apply(lambda x: 'search' in x.str.cat().lower()).reset_index(name='Flag')
# 100 loops, best of 3: 1.86 ms per loop

%%timeit
(df.groupby('Group')['string']
   .last()
   .str.contains('search', case=False)
   .astype(int)
   .rename('Flag')
   .reset_index())
# 100 loops, best of 3: 2.14 ms per loop
0 голосов
/ 28 января 2019

Использование str.contains:

(df.groupby('Group')['string']
   .last()
   .str.contains('search', case=False)
   .astype(int)
   .rename('Flag')
   .reset_index())

  Group  Flag
0     A     1
1     B     0
2     C     1

Аналогично выше (скопируйте или сбросьте индекс, чтобы избежать SettingWithCopyWarning).

u = df.drop_duplicates('Group', keep='last').reset_index(drop=True)
u['Flag'] = u.pop('string').str.contains('search', case=False).astype(int)
u

  Group  Flag
0     A     1
1     B     0
2     C     1
0 голосов
/ 28 января 2019

Вы можете попробовать:

df.groupby("Group")["string"] \
  .apply(lambda x: int("search" in x.values[-1].lower())) \
  .reset_index(name="Flag")

    Group   Flag
0   A   1
1   B   0
2   C   1

Функционально (в соответствии с комментарием ниже):

def last_search(df, word):
    return df.groupby("Group")["string"].apply(lambda x: int(word in x.values[-1].lower())).reset_index(name="Flag")

last_search(df, "search")
    Group   Flag
0   A   1
1   B   0
2   C   1

PS

То же самое можно сделать с другими ответами, какхорошо

0 голосов
/ 28 января 2019

Использование drop_duplicates с contains

yourdf=df.drop_duplicates('Group',keep='last').\
           assign(Flag=lambda x : x['string'].str.contains('Search'))
yourdf
Out[645]: 
   Group      string   Flag
5      A    Searches   True
10     B       Group  False
14     C  FullSearch   True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...