【问题标题】:How to uppercase acronyms in a dataframe如何在数据框中大写首字母缩写词
【发布时间】:2020-08-09 02:19:03
【问题描述】:

我有一个数据框df,其中包含我需要整齐格式化的公司名称。名称已经在标题中:

      Company Name     
0         Visa Inc    
1         Msci Inc
2    Coca Cola Inc
3         Pnc Bank
4         Aig Corp
5    Td Ameritrade 
6         Uber Inc
7       Costco Inc
8   New York Times

由于许多公司都使用首字母缩略词或缩写(行1345),我只希望这些公司名称中的第一个字符串是大写的,就像这样:

      Company Name     
0         Visa Inc    
1         MSCI Inc
2    Coca Cola Inc
3         PNC Bank
4         AIG Corp
5    TD Ameritrade 
6         Uber Inc
7       Costco Inc
8   New York Times

我知道我不能得到 100% 准确的替换,但我相信我可以通过只大写第一个字符串来接近:

  • 不超过 4 个字符
  • 并且第一个字符串不是字典中的单词

我怎样才能做到这一点:df['Company Name'] = df['Company Name'].replace()

【问题讨论】:

  • 老实说,这不是一件容易的事,因为例如,如果您尝试手动执行这些操作。你的逻辑是什么?
  • 是的,我知道这不会是完美的,但我认为通过使用上述规则的组合我可以达到大约 80%。其余的我可以手动清理。

标签: python string pandas replace


【解决方案1】:

手动解决方法可能是附加诸如“uber”之类的词

from nltk.corpus import words

dict_words = words.words()
dict_words.append('uber')  

创建一个新列

df.apply(lambda x : x['Company Name'].replace(x['Company Name'].split(" ")[0].strip(), x['Company Name'].split(" ")[0].strip().upper()) 
         if len(x['Company Name'].split(" ")[0].strip()) <= 4 and x['Company Name'].split(" ")[0].strip().lower() not in dict_words
         else x['Company Name'],axis=1)

输出:

0          Visa Inc
1          Msci Inc
2     Coca Cola Inc
3          PNC Bank
4          AIG Corp
5     TD Ameritrade
6          Uber Inc
7        Costco Inc
8    New York Times

运行下载nltk包版本:

import nltk
nltk.download()

演示:

from nltk.corpus import words

"new" in words.words()

输出:

 False

【讨论】:

  • Uber 是一个词(merriam-webster.com/dictionary/über-)?既然 Costco 超过 4 个字符,为什么还要大写?
  • 抱歉 ? 这是我的错字,uber 不被视为英文单词,因为它缺少字母 u 上方的重音
  • wordster 也是 merriam webster 网站的 python 包装器 from wordster import wordster # 获取给定单词的不同含义列表 print(wordster.find_meaning("uber")) 输出:['没有结果found'] 找不到 uber 的任何定义
【解决方案2】:

这将为您获取字符串中的第一个单词,并将其设置为仅用于包含在 include 列表中的公司名称:

import pandas as pd
import numpy as np

company_name = {'Visa Inc', 'Msci Inc', 'Coca Cola Ins', 'Pnc Bank'}

include = ['Msci', 'Pnc']

df = pd.DataFrame(company_name)
df.rename(columns={0: 'Company Name'}, inplace=True)

df['Company Name'] = df['Company Name'].apply(lambda x: x.split()[0].upper() + ' ' + x[len(x.split()[0].upper()):] if x.split()[0].strip() in include else x)


df['Company Name']

输出:

0        MSCI  Inc
1    Coca Cola Ins
2        PNC  Bank
3         Visa Inc
Name: Company Name, dtype: object

【讨论】:

  • 这行不通,因为它将不应该使用的单词大写(例如,Visa 和 Coca)。这两个都是字典中的实际单词,因此我建议不要将字典单词大写的规则。
  • @MSD 现在按照您建议的方式工作,但是首先创建一个包含您想要大写的缩写的列表会产生开销
  • 是的,我需要避免这种情况,因为我不会提前知道缩写
【解决方案3】:

因此,您实际上可以使用附魔模块来确定它是否是字典单词。鉴于您仍然会有一些结果 I.E.优步。

这是我想出的代码,很抱歉变量的名字很糟糕,什么不是。

import enchant
import pandas as pd


def main():
    d = enchant.Dict("en_US")
    listofcompanys = ['Msci Inc',
                      'Coca Cola Inc',
                      'Pnc Bank',
                      'Aig Corp',
                      'Td Ameritrade',
                      'Uber Inc',
                      'Costco Inc',
                      'New York Times']

    dataframe = pd.DataFrame(listofcompanys, columns=['Company Name'])
    for index, name in dataframe.iterrows():
        first_word = name['Company Name'].split()
        is_word = d.check(first_word[0])
        if not is_word:
            name['Company Name'] = first_word[0].upper() + ' ' + first_word[1]

    print(dataframe)



if __name__ == '__main__':
    main()

输出是:

         Company Name
0        MSCI Inc
1   Coca Cola Inc
2        PNC Bank
3        AIG Corp
4   TD Ameritrade
5        UBER Inc
6      Costco Inc
7  New York Times

【讨论】:

    【解决方案4】:

    这是一个有效的解决方案,它使用英文单词列表。只是 tduber 不准确,但就像你说的,这很难达到 100% 准确。

    url = 'https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt'
    
    words = set(pd.read_csv(url, header=None)[0])
    
    w1 = df['Company Name'].str.split()
    m1 = ~w1.str[0].str.lower().isin(words) # is not an english word
    m2 = w1.str[0].str.len().le(4) # first word is < 4 characters
    
    df.loc[m1 & m2, 'Company Name'] = w1.str[0].str.upper() + ' ' + w1.str[1:].str.join(' ')
    
         Company Name
    0        Visa Inc
    1        MSCI Inc
    2   Coca Cola Inc
    3        PNC Bank
    4        AIG Corp
    5   Td Ameritrade
    6        UBER Inc
    7      Costco Inc
    8  New York Times
    

    注意:我也尝试过使用 nltk 包,但显然,nltk.corpus.words 模块还没有完整的英文单词。

    【讨论】:

    • 但是 Uber 不是一个词吗 (merriam-webster.com/dictionary/über-)?另外,TD 不是一个词,为什么不能大写。
    • 这不是完美的,就像你说的,这永远不是完美的可解决的。这应该可以达到您预期的 80%。
    • 是的,我认为这让我最接近。感谢您的帮助。
    【解决方案5】:

    您可以先将第一个单词和其他部分分开。然后根据您的逻辑过滤这些第一个词:

    company_list = ['Visa']
    
    s = df['Company Name'].str.extract('^(\S+)(.*)')
    
    mask = s[0].str.len().le(4) & (~s[0].isin(company_list))
    df['Company Name'] = s[0].mask(mask, s[0].str.upper()) + s[1]
    

    输出(注意New York 中的NEW 也发生了变化):

         Company Name
    0        Visa Inc
    1        MSCI Inc
    2   COCA Cola Inc
    3        PNC Bank
    4        AIG Corp
    5   TD Ameritrade
    6        UBER Inc
    7      Costco Inc
    8  NEW York Times
    

    【讨论】:

    • 我没有现有的公司名单可供比较。这就是为什么我认为排除字典中已经存在的单词,而那些超出一定长度的单词可能是更好的方法。
    • 您当然可以将字典传递给isin,而不是company_list。我只是把它作为一个例子。
    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    相关资源
    最近更新 更多