#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’)