Создать новый столбец с соответствующим значением между уникальным набором элементов и длинным списком - PullRequest
0 голосов
/ 07 сентября 2018

Я новичок в обработке данных в Python. У меня есть столбец в кадре данных, который имеет такой текст:

  • Мне очень нравится Продукт A!
  • Я думаю, что Продукт B для меня!
  • Я пойду с продуктом C.

Моя цель - создать новый столбец с названием продукта (включая слово «Продукт»). Я не хочу использовать Regex. Название продукта является уникальным в ряду. Так что не будет строки со строкой, такой как

  • Мне очень нравится продукт A и продукт B

Проблема в общем виде : У меня есть список уникальных предметов. давайте назовем его списком А. У меня есть еще один список строк, где каждая строка содержит не более одного элемента из списка А. Как мне создать новый список с соответствующим элементом.

Я написал следующий код. Работает нормально. Но даже я (новичок в программировании) могу сказать, что это крайне неэффективно.

Есть ли лучшее и элегантное решение?

product_type = ['Product A', 'Product B', 'Product C', 'Product D']
product_list = [None] * len(fed_df['product_line'])
for i in range(len(product_list)):
    for product in product_type:
        if product in fed_df['product_line'][i]:
            product_list[i] = product
fed_df['product_line'] = product_list

1 Ответ

0 голосов
/ 07 сентября 2018

Короткий фон

По сути, в какой-то момент каждый элемент каждого списка необходимо сравнивать аналогично тому, как вы его написали (хотя вы можете перейти к следующему циклу, когда совпадение будет найдено). Но хитрость в написании хорошего кода на Python состоит в том, чтобы использовать функциональность, написанную на более низком уровне, для эффективности, а не пытаться писать это самостоятельно. Например: вы должны избегать использования

for i in range(len(myList)): #code which accesses myList[i]

когда вы можете использовать

for myListElement in myList: #code which uses myListElement 

, поскольку в последнем случае доступ к myList обрабатывается внутренне и более эффективно, чем вычисление i вручную с помощью python, а затем доступ к элементу i th в myList. Этот факт справедлив и для некоторых других языков программирования высокого уровня.

Фактический ответ

В любом случае, чтобы ответить на ваш вопрос, я придумал следующее и считаю, что это будет более эффективно:

answer = map(lambda product_line_element: next(filter(lambda product: product in product_line_element,product_type),None), fed_df['product_line'])

Что он делает, это отображает каждую строку (map) в fed_df ['product_line'] и заменяет этот элемент первым элементом (next) в списке, содержащем типы продуктов, найденные в каждой строке продуктов в fed_df [' product_line '] (фильтр).

Как я тестировал

Чтобы проверить это, я составил список списков для использования в качестве fed_df ['productline']

[['h', 'a', 'g'], ['k', 'b', 'l'], ['u', 't', 'a'], ['r', 'e', 'p'], ['g', 'e', 'b']]

и искал "a" и "b" "product_types", что дало

['a', 'b', 'a', None, 'b']

в результате, что, я думаю, то, что вы после ...

Эти функции отображения обычно предпочтительнее, чем для циклов, поскольку они не допускают мутации и могут быть легко сделаны многопоточными / многопроцессорными.

Другим преимуществом этих решений является то, что результат не рассчитывается до тех пор, пока будущий код не попытается получить доступ к ответу, что немного увеличит использование ЦП. Вы можете принудительно рассчитать его путем преобразования ответа в список (list (answer)), но в этом нет необходимости.

Надеюсь, я правильно понял вашу проблему. Дайте мне знать, если у вас есть какие-либо вопросы :)

...