PYTHON — проверьте, содержит ли ячейка строку из другой ячейки

Я хочу создать столбец «Проведено?» в моем кадре данных pandas, который помечается всякий раз, когда символ в одной из ячеек «DrpType» содержится в другой ячейке «HeldDrpTypes» из той же строки.

Я пробовал использовать where и in, но это не сработало:

df['Held?'] = where(df['DrpType'] in df['HeldDrpTypes'] == True),'Yes','No')

Вот чего я хочу добиться:

> print(df)
      DrpType     HeldDrpTypes     Held?    
0       A              B            No
1       B              BC           Yes
2       C              B            No
3       B              BC           Yes
4       A              BC           No
5       C              BC           Yes

Любые идеи, как я могу это сделать?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
2 489
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете проверить

l=['Yes' if x in y else 'No' for x , y in zip(df.DrpType,df.HeldDrpTypes)]
l
Out[196]: ['No', 'Yes', 'No', 'Yes', 'No', 'Yes']


df['Held']=l

Или воспользуемся методом из numpy

np.core.chararray.find(df.HeldDrpTypes.values.astype(str),df.DrpType.values.astype(str))!=-1
Out[201]: array([False,  True, False,  True, False,  True])

Интересно о таймингах, я думаю, что понимание списка может быть более чем в 1000 раз быстрее, чем метод apply

Erfan 15.04.2019 01:36

Если вам интересно, сделал некоторые тайминги

Erfan 15.04.2019 01:52
Ответ принят как подходящий

Для чистого пути панд вы можете использовать df.apply()

import pandas as pd
df = pd.DataFrame({
    'DrpType': ['A', 'B', 'C', 'B', 'A', 'C',],
    'HeldDrpTypes':['B', 'BC', 'B', 'BC', 'BC', 'BC']
})

df['Held?'] = df.apply(lambda row: row['DrpType'] in row['HeldDrpTypes'], axis=1)

print(df)
#   DrpType HeldDrpTypes  Held?
# 0       A            B  False
# 1       B           BC   True
# 2       C            B  False
# 3       B           BC   True
# 4       A           BC  False
# 5       C           BC   True

Если вы сторонник Yes/No, а не True/False, вы можете использовать следующее, но я бы посоветовал придерживаться двоичного кода True/False, чтобы упростить проверку на правдивость, а не анализировать строку.

df['Held?'] = df.apply(
    lambda row: 'Yes' if row['DrpType'] in row['HeldDrpTypes'] else 'No', axis='columns')

print(df)
#   DrpType HeldDrpTypes Held?
# 0       A            B    No
# 1       B           BC   Yes
# 2       C            B    No
# 3       B           BC   Yes
# 4       A           BC    No
# 5       C           BC   Yes

Мне было интересно узнать время обоих ответов, поэтому я проверил их, используя больший фрейм данных:

df = pd.concat([df]*100000, ignore_index=True)

print(df.shape)

(600000, 2)

Тайминги:

Вен-Бенс ответьте list comprehension:

%%timeit

df['Held'] = ['Yes' if x in y else 'No' for x , y in zip(df.DrpType,df.HeldDrpTypes)]

Выдает следующее:

304 ms ± 17.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Брайан Коханс ответьте, используя .apply

%%timeit

df['Held?'] = df.apply(
    lambda row: 'Yes' if row['DrpType'] in row['HeldDrpTypes'] else 'No', axis='columns')

Выдает следующее:

23.2 s ± 1.23 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

Таким образом, разница в скорости на самом деле составляет +- 1000 в пользу list comprehension

Это смешно! Хотя я думаю, я не очень шокирован тем, что понимание, являющееся родной идиомой Python, работает над двумя сериями быстрее, чем что-то, построенное с помощью Python, тащащего все содержимое фрейма данных. Это немного шокирует для фрейма данных буквально с двумя столбцами, но мне не хотелось бы думать о разнице во времени с более сложным фреймом данных. Спасибо за тестирование разницы. Очевидно, что нужно учитывать реальный размер ваших данных и удобочитаемость, но я обязательно должен помнить об этом в будущем.

Cohan 15.04.2019 03:11

Я и сам просчитывал цифры. Понимание списка с выводом Yes/No: 62 мс, метод numpy с выводом True/False: 456 мс. df.apply() метод с любым выходом: 11,7 с.

Cohan 15.04.2019 03:54

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