[英]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
和一个逗号, +
是前一个表达式的重复计数,在这种情况下为空格)。 此模式还与Criollo, Forastero
Criollo,
中的Criollo, Forastero
相匹配。 由于这实际上替换删除,
(逗号和空格),你会得到CriolloForastero
。
要解决此问题,请将此模式更改为Criollo, \\+
(用反斜杠将+
来,以按实际方式匹配它们)。
您的替换列表中可能不需要['Criollo\\+', 'Criollo']
。
您也可以尝试其他方法:
应用于每个bean_type
字段的函数应:
Blend
(任何位置)。 如果是这样,则返回Blend
。 findall
的结果是所有“发现”的列表。 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.6和Jupyter 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.