我想从名称列中提取某个字符之前的单词,并将新的列添加为颜色
如果名称前没有颜色,那么我想显示空字符串
我一直在尝试在比赛之前提取单词。例如,我有下表:
import pandas as pd
import re
data = ['red apple','green topaz','black grapes','white grapes']
df = pd.DataFrame(data, columns = ['Names'])
Names
red apple
green apple
black grapes
white grapes
normal apples
red apple
下面的代码我很害怕 我正在争取部分输出
df['Names'].apply(lambda x: ' '.join(re.findall(r'(\w+)\s+apple', x)))
df['Names'].apply(lambda x: ' '.join(re.findall(r'(\w+)\s+apple|grapes', x)))
所需的输出:
Names color
red apple red
green apple green
black grapes black
white grapes white
normal apples
red apple red
请帮我解决这个问题
答案 0 :(得分:2)
我找到了这个解决方案: 给我一个像['red','green','black','white','']
的color_columnimport re
data = ['red apple','green topaz','black grapes','white grapes','apples']
colors_column = list(map(lambda x: ' '.join(re.findall(r'(\S\w+)\s+\w+', x)) ,data))
答案 1 :(得分:1)
不一定是个绝妙的把戏,但这似乎可行:
((re.search('(\w*) (apple|grape)',a)) or ['',''])[1]
简而言之,您搜索的是苹果或葡萄之前的第一个单词,但是如果没有匹配项,它将返回None
,这是错误的。因此,您可以使用或使用空字符串列表,但是由于要获取匹配表达式的第一个元素(索引1),因此我使用了空字符串的两个元素列表(在那里获取了第二个元素)。
答案 2 :(得分:1)
一种解决方案是删除 fruit 名称以获取颜色:
def remove_fruit_name(description):
return re.sub(r"apple|grapes", "", description)
df['Colors'] = df['Names'].apply(remove_fruit_name)
如果您有很多行,则编译正则表达式可能会更快:
fruit_pattern = re.compile(r"apple|grapes")
def remove_fruit_name(description):
return fruit_pattern.sub("", description)
另一种解决方案是使用 lookahead断言,(可能)速度更快,但是代码稍微复杂一些:
# That may be useful to have a set of fruits:
valid_fruit_names = {"apple", "grapes"}
any_fruit_pattern = '|'.join(valid_fruit_names)
fruit_pattern = re.compile(f"(\w*)\s*(?={any_fruit_pattern})")
def remove_fruit_name(description):
match = fruit_pattern.search(description)
if match:
return match.groups()[0]
return description
df['Colors'] = df['Names'].apply(remove_fruit_name)
以下是文档中引用的前瞻示例:
(?=...)
如果
...
下一个匹配,则匹配,但不使用任何字符串。这称为超前断言。例如,Isaac (?=Asimov)
仅在其后跟'Isaac '
时才匹配'Asimov'
。
最后,如果要使normal
和green
之间有所不同,您将需要一个有效颜色的字典。如果输入中包含非水果字符串,例如topaz
,则水果名称也是如此。