#python #pandas
Вопрос:
Это пример проблемы, которую мне нужно решить. У меня есть 2 таблицы, и я должен найти подстроку(dff2) в строке(dff). И если подстрока в строке существует, добавьте эту строку в выходной кадр данных. Проблема в том, что я написал код с использованием циклов, и он работает слишком медленно для тысяч строк. Как я мог переписать код, используя методы pandas?
data = {'long string column': ['aaaabbbbccccdddd', 'bbbbccccddddeeee','ccccddddeeeeffff','ddddeeeeffffgggg'],}
dff = pd.DataFrame(data, columns = ['long string column'])
data2 = {'substring_column': ['aaaa', 'bbbb','cccc','dddd'], 'status': ['best', 'good','bad','worst'],}
dff2 = pd.DataFrame(data2, columns = ['substring_column','status'])
df_output = pd.DataFrame()
df_output_small = pd.DataFrame()
for i in range(len(dff2)):
df_output_small = dff[(dff['long string column'].str.contains(dff2['substring_column'].iloc[i]))]
df_output_small['status'] = dff2['status'].iloc[i]
df_output = df_output.append(df_output_small, ignore_index=True)
df_output
Ответ №1:
Используйте Series.str.extractall
для всех подстрок, а затем справа merge
:
pat = f'({"|".join(dff2["substring_column"])})'
Если есть некоторые подстроки, которые должны быть регулярными выражениями, используйте re.escape
:
import re
pat = '|'.join(re.escape(x) for x in dff2['substring_column'])
df = (dff.set_index('long string column', drop=False)['long string column']
.str.extractall(pat)[0]
.reset_index(level=1, drop=True)
.reset_index(name='substring_column'))
df = df.merge(dff2, on='substring_column', how='right')
print (df)
long string column substring_column status
0 aaaabbbbccccdddd aaaa best
1 aaaabbbbccccdddd bbbb good
2 bbbbccccddddeeee bbbb good
3 aaaabbbbccccdddd cccc bad
4 bbbbccccddddeeee cccc bad
5 ccccddddeeeeffff cccc bad
6 aaaabbbbccccdddd dddd worst
7 bbbbccccddddeeee dddd worst
8 ccccddddeeeeffff dddd worst
9 ddddeeeeffffgggg dddd worst
Последний substring_column
столбец удаления:
df = df.drop('substring_column', axis=1)
Комментарии:
1. Это сработало для примера, который я написал выше, но это вызывает ошибку для подзвенков, таких как «aa(aa» (говорит, что отсутствует»)»). К сожалению, в моей проблеме есть такие глупые подстроки. Как бы я переписал код? P.S. В любом случае спасибо за помощь. И поскольку ваш код работает для wxample, я подтверждаю это!)