Обновление значения фрейма данных на основе списка

#python #pandas #nested-loops

#python #панды #вложенные циклы

Вопрос:

У меня есть фрейм данных, основанный на строках в столбце с именем «создатель», я хотел бы проверить, есть ли в строке слово, которое находится в другом списке. Если строка содержит слово, которое находится в указанном списке, обновите столбец originator_prediction на «org».

Есть ли лучший способ сделать это? Я сделал это следующим образом, но медленно.

 for row in df['ORIGINATOR'][1:]:
    string = str(row)
    splits = string.split()
    for word in splits:
        if word in COMMON_ORG_UNIGRAMS_LIST:
            df['ORGINATOR_PREDICTION'] = 'Org'
        else:
            continue
  
 
df  = pd.DataFrame({'ORIGINATOR':  ['JOHN DOE', 'APPLE INC', 'MIKE LOWRY'],
        'ORGINATOR_PREDICTION': ['Person', 'Person','Person']})

COMMON_ORG_UNIGRAMS_LIST = ['INC','LLC','LP']
  

Конкретно, если вы посмотрите на строку 2 в нашем фрейме данных, у «APPLE INC» должен быть originator_prediction = ‘ORG’, а не person.

Причина в том, что мы перебрали наш общий список организационных unigrams, и там было слово INC.

Комментарии:

1. Я бы сказал, да, можете ли вы опубликовать некоторые примеры данных и ожидаемый результат?

2. Скотт добавил еще немного информации к вопросу

Ответ №1:

Ваш код не даст правильного результата, потому что после каждой проверки с df['ORGINATOR_PREDICTION'] = 'Org' помощью вы присваиваете всем строкам в этом столбце это значение. Это приведет к тому, что все строки в этом столбце будут иметь значение Org . Кроме того, я не понимаю, почему вы добавили [1:] в цикл. Он не выбирает имя столбца, если это то, чего вы пытались избежать. Я внес некоторые изменения в ваш код, он работает по желанию

 org_or_person_list = []
for row in df['ORIGINATOR']:
    splits = row.split()
    org_or_person_list.append('Org' if set(splits) amp; set(COMMON_ORG_UNIGRAMS_LIST) else 'Person')

df['ORGINATOR_PREDICTION'] = org_or_person_list
  

Вывод:

     ORIGINATOR  ORGINATOR_PREDICTION
0   JOHN DOE    Person
1   APPLE INC   Org
2   MIKE LOWRY  Person
  

Комментарии:

1. Спасибо за изменение моего исходного кода, есть ли более эффективный способ написать это? Для запуска требуется много времени. У меня примерно 800 тыс. строк для контекста.

2. Я отредактировал его. Теперь это более эффективно. Кроме того, я удалил string = str(row) , поскольку каждая строка уже была строкой, но вы можете добавить ее обратно, если другие строки имеют другой тип данных

3. Хотя я думаю, что это работает и намного эффективнее, я думаю, мне нужно вернуться к чертежной доске и выяснить, как выполнить это через 800 тыс. строк. Это никогда не заканчивается… Я собираюсь попробовать разделить строку на начало времени и создать столбец со всеми разделениями строк. Возможно, используйте некоторые массивы numpy для ускорения процесса..

4. Я мог бы помочь, если вы можете предоставить мне данные. Совет, который я могу дать, заключается в том, что если организационные униграммы (INC, LLP и т. Д.) Всегда Находятся в конце, Тогда вам нужно только прочитать последнее слово splits и отбросить остальное.

5. @mikelowry Привет. Я еще больше отредактировал свой код. Повторное присвоение каждой строке фрейма данных является трудоемким процессом. Я добавил результаты в список и присвоил его столбцу за один раз. (Я не воспользовался splits советом из моего предыдущего комментария.)

Ответ №2:

Попробуйте это, используя .str , средство доступа к строке, с contains помощью метода. Мы можем создать регулярное выражение, используя join для списка строк:

 df.loc[df['ORIGINATOR'].str.contains('|'.join(COMMON_ORG_UNIGRAMS_LIST)), 'ORGINATOR_PREDICTION'] = 'Org'
  

Вывод:

    ORIGINATOR ORGINATOR_PREDICTION
0    JOHN DOE               Person
1   APPLE INC                  Org
2  MIKE LOWRY               Person
  

Полный код:

 df  = pd.DataFrame({'ORIGINATOR':  ['JOHN DOE', 'APPLE INC', 'MIKE LOWRY'],
        'ORGINATOR_PREDICTION': ['Person', 'Person','Person']})

COMMON_ORG_UNIGRAMS_LIST = ['INC','LLC','LP']

df.loc[df['ORIGINATOR'].str.contains('|'.join(COMMON_ORG_UNIGRAMS_LIST)),'ORGINATOR_PREDICTION'] = 'Org'

print(df)
  

Комментарии:

1. получение следующей ошибки: объекты Series изменчивы, поэтому их нельзя хэшировать

2. Является ли COMMON_ORN_UNIGRAMS_LIST серией?

3. COMMON_ORG_UNIGRAMS_LIST — это список — df[‘ORIGINATOR’] — это объект

4. да, у меня заканчивается память до завершения операции.

Ответ №3:

Альтернативное решение:

 df  = pd.DataFrame({
    'ORIGINATOR':  ['JOHN DOE', 'APPLE INC', 'MIKE LOWRY'],
    'ORIGINATOR_PREDICTION': ['Person', 'Person','Person']
})

COMMON_ORG_UNIGRAMS_LIST = ['INC','LLC','LP']

df.loc[df['ORIGINATOR'].apply(lambda x: len(set(x.split(' ')) amp; set(COMMON_ORG_UNIGRAMS_LIST)) > 0), 'ORIGINATOR_PREDICTION'] = 'Org'
    
  

Комментарии:

1. получение ошибки индексации: Имя: СОЗДАТЕЛЬ, Длина: 7601, dtype: bool, ‘ORIGINATOR_PREDICTION’)