繁体   English   中英

用Python中的数字和符号替换列表的功能

[英]Function to replace list with numbers and signs in python

我有一个数组:

array(['Amazon', 'Amazon mix', 'Amazon, ICS', 'Beniano', 'Blend',
   'Blend-Forastero,Criollo', 'CCN51', 'Criollo', 'Criollo (Amarru)',
   'Criollo (Ocumare 61)', 'Criollo (Ocumare 67)',
   'Criollo (Ocumare 77)', 'Criollo (Ocumare)', 'Criollo (Porcelana)',
   'Criollo (Wild)', 'Criollo, +', 'Criollo, Forastero',
   'Criollo, Trinitario', 'EET', 'Forastero', 'Forastero (Amelonado)',
   'Forastero (Arriba)', 'Forastero (Arriba) ASS',
   'Forastero (Arriba) ASSS', 'Forastero (Catongo)',
   'Forastero (Nacional)', 'Forastero (Parazinho)',
   'Forastero(Arriba, CCN)', 'Forastero, Trinitario', 'Matina',
   'NA_bean', 'Nacional', 'Nacional (Arriba)', 'Other', 'Trinitario',
   'Trinitario (85% Criollo)', 'Trinitario (Amelonado)',
   'Trinitario (Scavina)', 'Trinitario, Criollo',
   'Trinitario, Forastero', 'Trinitario, Nacional',
   'Trinitario, TCGA'], dtype=object)

我想标准化它们以删除唯一值的数量。 所以我创建了一个函数:

def std_bean(text):
    replace = [
        ['\(',''],['\)',''],
        ['Amazon mix|Amazon, ICS|Blend-Forastero,Criollo|Criollo, Trinitario|Forastero, Trinitario|Trinitario 85% Criollo|Trinitario, Criollo|Trinitario, Forastero|Trinitario, Nacional','Blend'],
        ['Forastero Arriba|Forestero ASS|Forestero ASSS|Forastero Nacional|Forastero Catongo|Forastero Parazinho|Forastero Arriba ASS|ForasteroArriba, CCN|Forastero Arriba ASSS|Forastero Amelonado','Forastero'],
        ['Criollo Ocumare 77', 'Criollo'],
        ['Criollo Ocumare 61', 'Criollo'],
        ['Criollo Ocumare', 'Criollo'],
        ['Criollo Wild', 'Criollo'],
        ['Criollo, +', 'Criollo'],
        ['Criollo+', 'Criollo'],
        ['Criollo 67', 'Criollo'],
        ['Criollo, Forastero', 'Criollo'],
        ['Criollo Amarru', 'Criollo'],
        ['Forestero ASSS', 'Forastero'],
        ['Forastero ASS', 'Forastero'],
        ['Forestero', 'Forastero'],
        ['Trinitario Amelonado', 'Trinitario'],
        ['Forestero ASSS', 'Forastero'],
        ['Nacional Arriba', 'Nacional'],
        ['Trinitario, TCGA', 'Trinitario'],
        ['Criollo Porcelana','Criollo'],
        ['ForasteroS', 'Forastero']
    ]
    for i, j in replace:
        text = re.sub(i, j, text)
    return(text)
df['bean_type'].str.replace('.','').apply(std_bean).unique()

应用后,我仍然有一个值,例如'Criollo +','CriolloForastero'和其他我无法替代的值,我不知道如何解决...

array(['NA_bean', 'Criollo', 'Trinitario', 'Forastero', 'Blend', 'CCN51',
   'Nacional', 'Beniano', 'Criollo+', 'Amazon', 'EET',
   'Trinitario Scavina', 'CriolloForastero', 'Matina', 'Other'],
  dtype=object)

有人可以帮我改善功能吗? 我只想合并相同的内容。 将具有超过一种类型的bean(带有逗号或在其内用逗号表示混合或具有另一种类型的豆的名称)的标记为Blend,并为那些没有这种类型的豆留下不在括号中的名称融合。

我想要的最终输出是只有'Blend,Criolo,Forastero,NA_bean,Matina,Nacional等'

我想将它们归类为Blend:“ Amazon mix | Amazon,ICS | Blend-Forastero,Criollo | Criollo,Trinitario | Forastero,Trinitario | Trinitario 85%Criollo | Trinitario,Criollo | Trinitario,Forastero | Trinitario,Nacional”

我想将这些作为Forastero:['Forastero Arriba | Forestero ASS | Forestero ASSS | Forastero Nacional | Forastero Catongo | Forastero Parazinho | Forastero Arriba ASS | ForasteroArriba,CCN | Forastero Arriba ASSS | Forastero Amelonado','Forastero']

等等。

问题的根源是Criollo, +用作正则表达式模式。

请注意,此模式实际上意味着:

  • 找到Criollo和一个逗号,
  • 然后找到一个出现1次或更多次的空格(正则表达式中的+是前一个表达式的重复计数,在这种情况下为空格)。

此模式还与Criollo, Forastero Criollo,中的Criollo, Forastero相匹配。 由于这实际上替换删除, (逗号和空格),你会得到CriolloForastero

要解决此问题,请将此模式更改为Criollo, \\+ (用反斜杠将+来,以按实际方式匹配它们)。

您的替换列表中可能不需要['Criollo\\+', 'Criollo']

编辑

您也可以尝试其他方法:

应用于每个bean_type字段的函数应:

  1. 检查文本是否包含Blend (任何位置)。 如果是这样,则返回Blend
  2. 查找所有单词(字母序列)-Bean名称。 当模式包含单个捕获组时, findall的结果是所有“发现”的列表。
  3. 如果仅找到一个单词 (结果列表仅包含一项),则仅返回该项。
  4. 否则(找到多个 bean名称)返回Blend

下面有一个示例程序:

import pandas as pd
import re
def std_bean_name(text):
    """Generate standard bean name"""
    if re.search('Blend', text, re.IGNORECASE):
        return 'Blend'
    res = re.findall(r"([a-z]+)", text, re.IGNORECASE)
    if len(res) == 1:
        return res[0]
    else:
        return 'Blend'
# Source data
lst = ['Amazon', 'Amazon mix', 'Amazon, ICS', 'Beniano', 'Blend',
    'Blend-Forastero,Criollo', 'CCN51', 'Criollo', 'Criollo (Amarru)',
    'Criollo (Ocumare 61)', 'Criollo (Ocumare 67)',
    'Criollo (Ocumare 77)', 'Criollo (Ocumare)', 'Criollo (Porcelana)',
    'Criollo (Wild)', 'Criollo, +', 'Criollo, Forastero',
    'Criollo, Trinitario', 'EET', 'Forastero', 'Forastero (Amelonado)',
    'Forastero (Arriba)', 'Forastero (Arriba) ASS',
    'Forastero (Arriba) ASSS', 'Forastero (Catongo)',
    'Forastero (Nacional)', 'Forastero (Parazinho)',
    'Forastero(Arriba, CCN)', 'Forastero, Trinitario', 'Matina',
    'NA_bean', 'Nacional', 'Nacional (Arriba)', 'Other', 'Trinitario',
    'Trinitario (85% Criollo)', 'Trinitario (Amelonado)',
    'Trinitario (Scavina)', 'Trinitario, Criollo',
    'Trinitario, Forastero', 'Trinitario, Nacional', 'Trinitario, TCGA']
# Create a DataFrame
beans = pd.DataFrame(data=lst, columns=['bean_type'])
# Generate standard bean names
beans['type2'] = beans['bean_type'].apply(std_bean_name)
# Show the detailed result (source / standard type)
print(beans)
# List unique bean names
print(beans['type2'].unique())

最后一行打印:

['Amazon' 'Blend' 'Beniano' 'CCN' 'Criollo' 'EET' 'Forastero' 'Matina'
 'Nacional' 'Other' 'Trinitario']

我在Python 3.6Jupyter Notebook下测试了上述程序。

欢迎使用StackOverflow,看来我们必须建立自定义规则,而不是查找和替换。

请找到以下代码,并检查是否适合您,

import pandas as pd

bean_type = {'bean_type': ['Amazon', 'Amazon mix', 'Amazon, ICS', 'Beniano', 'Blend',
                           'Blend-Forastero,Criollo', 'CCN51', 'Criollo', 'Criollo (Amarru)',
                           'Criollo (Ocumare 61)', 'Criollo (Ocumare 67)',
                           'Criollo (Ocumare 77)', 'Criollo (Ocumare)', 'Criollo (Porcelana)',
                           'Criollo (Wild)', 'Criollo, +', 'Criollo, Forastero',
                           'Criollo, Trinitario', 'EET', 'Forastero', 'Forastero (Amelonado)',
                           'Forastero (Arriba)', 'Forastero (Arriba) ASS',
                           'Forastero (Arriba) ASSS', 'Forastero (Catongo)',
                           'Forastero (Nacional)', 'Forastero (Parazinho)',
                           'Forastero(Arriba, CCN)', 'Forastero, Trinitario', 'Matina',
                           'NA_bean', 'Nacional', 'Nacional (Arriba)', 'Other', 'Trinitario',
                           'Trinitario (85% Criollo)', 'Trinitario (Amelonado)',
                           'Trinitario (Scavina)', 'Trinitario, Criollo',
                           'Trinitario, Forastero', 'Trinitario, Nacional',
                           'Trinitario, TCGA']}

df = pd.DataFrame(bean_type)


def blend_count(text):
    bean_types = ['criollo', 'trinitario', 'nacional', 'forastero']
    _blend_count = 0
    if 'blend' in text.lower():
        return 0
    for _bean_type in bean_types:
        if _bean_type in text.lower():
            _blend_count += 1
    return _blend_count


def blend_category(text):
    _blend_count = blend_count(text)
    _text = text.lower()
    if any(x in _text for x in ['blend', 'amazon']):
        return 'Blend'
    elif 'trinitario' in _text:
        if _blend_count == 1:
            return 'Trinitario'
        elif _blend_count > 1:
            return 'Blend'
    elif _text.startswith('forastero'):
        return 'Forastero'
    elif _text.startswith('nacional'):
        return 'Nacional'
    elif _text.startswith('criollo'):
        return 'Criollo'
    else:
        return text


df['blend_category'] = df['bean_type'].apply(blend_category)
# df['blend_count'] = df['bean_type'].apply(blend_count)

print(df)

以下是我的输出

                   bean_type blend_category
0                     Amazon          Blend
1                 Amazon mix          Blend
2                Amazon, ICS          Blend
3                    Beniano        Beniano
4                      Blend          Blend
5    Blend-Forastero,Criollo          Blend
6                      CCN51          CCN51
7                    Criollo        Criollo
8           Criollo (Amarru)        Criollo
9       Criollo (Ocumare 61)        Criollo
10      Criollo (Ocumare 67)        Criollo
11      Criollo (Ocumare 77)        Criollo
12         Criollo (Ocumare)        Criollo
13       Criollo (Porcelana)        Criollo
14            Criollo (Wild)        Criollo
15                Criollo, +        Criollo
16        Criollo, Forastero        Criollo
17       Criollo, Trinitario          Blend
18                       EET            EET
19                 Forastero      Forastero
20     Forastero (Amelonado)      Forastero
21        Forastero (Arriba)      Forastero
22    Forastero (Arriba) ASS      Forastero
23   Forastero (Arriba) ASSS      Forastero
24       Forastero (Catongo)      Forastero
25      Forastero (Nacional)      Forastero
26     Forastero (Parazinho)      Forastero
27    Forastero(Arriba, CCN)      Forastero
28     Forastero, Trinitario          Blend
29                    Matina         Matina
30                   NA_bean        NA_bean
31                  Nacional       Nacional
32         Nacional (Arriba)       Nacional
33                     Other          Other
34                Trinitario     Trinitario
35  Trinitario (85% Criollo)          Blend
36    Trinitario (Amelonado)     Trinitario
37      Trinitario (Scavina)     Trinitario
38       Trinitario, Criollo          Blend
39     Trinitario, Forastero          Blend
40      Trinitario, Nacional          Blend
41          Trinitario, TCGA     Trinitario

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM