#python #pandas #string #string-matching
#python #pandas #строка #сопоставление строк
Вопрос:
У меня есть серия, в которой содержатся компании, и они объединяют названия акций:
stock
0 AAPLApple
1 AMZNAmazon.com
2 FBFacebook
3 NFLXNetflix
4 INTCIntel
5 TSLATesla
6 MUMicron Technology
7 MSFTMicrosoft
8 NVDANVIDIA
9 CSCOCisco Systems
11 LULULululemon Athletica
12 EBAYeBay
13 AVGOBroadcom
14 QCOMQUALCOMM
15 GILDGilead Sciences
16 WDCWestern Digital
17 GOOGLAlphabet
18 BIIBBiogen
19 GOOGAlphabet
20 URBNUrban Outfitters
21 NTAPNetApp
22 AABAAltaba
23 SBUXStarbucks
24 CELGCelgene
25 SPLKSplunk
26 COSTCostco Wholesale
27 AMDAdvanced Micro Devices
28 PYPLPaypal
29 REGNRegeneron Pharmaceuticals
30 AMATApplied Materials
...
Name: stock, Length: 243, dtype: object
У меня также есть список символов stocks для сопоставления:
['ETSY',
'COUP',
'TSLA',
'CRWD',
'ROKU',
'A',
'AAL',
'AAP',
'AAPL',
'ABBV',
'AEP',
'AES',
'AFL',
'HUBS',
'AIG',
'AIV',
'AIZ',
'AJG',
'AKAM',
'ALB',
'ALGN',
'ALK',
'ALL',
'ALLE',
'ALXN',
'AMAT',
'AMCR',
'AMD',
'AME',
'AMGN',
'AMP',
'AMT',
'AMZN',
...]
Я хочу сопоставить, чтобы удалить каждое имя в столбце акций полного названия компании и оставить только символ, если символ не найден, затем удалите строку.
мой код до сих пор:
def clean_name(name):
companies = list(COMPANIES.keys())
for company in companies:
if company in name:
return company
return None
def sort_df():
df[STOCK] = df[STOCK].apply(lambda x: clean_name(x))
df = df.dropna()
return df
проблема в том, что каждое сопоставление строк в большинстве случаев возвращает только одну букву.
итак, результат:
0 A
1 A
2 F
3 F
4 C
5 TSLA
6 MU
7 F
8 A
9 C
11 A
12 A
13 A
14 A
15 D
16 C
17 A
18 BIIB
19 A
20 O
21 A
22 A
23 SBUX
24 C
25 SPLK
26 C
27 A
28 L
29 RE
30 A
...
Комментарии:
1. проверьте список стандартных символов, я думаю, что есть односимвольные выходы, такие как ‘A’, ‘F’ и т. Д., Поэтому его возвращаемый одиночный символ, также другое — return None должен быть вне цикла for итак, ваш цикл повторяется только один раз, а не для всего списка
Ответ №1:
Одна из идей — обратная сортировка по длине для сопоставления первых самых длинных названий компаний:
def clean_name(name):
companies = list(COMPANIES.keys())
for company in sorted(companies, key=len, reverse=True):
if company in name:
return company
return None
Ответ №2:
Другим способом решения этой проблемы было бы скомпилировать строку регулярного выражения с исходными символами и выполнить сопоставление со stock
столбцом в DataFrame.
Например:
import re
# Build regex string.
exp_s = '|'.join('^{}'.format(i) for i in sorted(s, key=len, reverse=True))
exp = re.compile('({})'.format(exp_s))
# Match symbols using regex.
df['stock'].str.extract(exp).dropna()
Где:
# Stock symbols list.
s = ['AAPL', 'AMZN', 'FB', 'NFLX', ...]
Вывод:
0 AAPL
1 AMZN
2 FB
3 NFLX
...
26 AMD
27 PYPL
28 REGN
29 AMAT