Pandas, почему сопоставление строк останавливается на первой букве

#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