将列表简化为类别

2024-06-16 11:43:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我是一个新的Python开发人员,想知道是否有人能帮我解决这个问题。我有一个数据集,其中有一列描述公司类型。我注意到专栏里有,例如,外科手术,外科手术。它有眼镜,眼镜和验光列出。因此,我不想在本专栏中列出一个庞大的列表,我只想简单地说,如果你找到一个包含“eye”、“glasses”或“opto”的单词,那么就把它改成“eyewear”。我的初始代码如下所示:

def map_company(row):
    company = row['SIC_Desc']
    if company in 'Surgical':
         return 'Surgical'
    elif company in ['Eye', 'glasses', 'opthal', 'spectacles', 'optometers']:
        return 'Eyewear'
    elif company in ['Cotton', 'Bandages', 'gauze', 'tape']:
        return 'First Aid'
    elif company in ['Dental', 'Denture']:
        return 'Dental'
    elif company in ['Wheelchairs', 'Walkers', 'braces', 'crutches', 'ortho']:
        return 'Mobility equipments'
    else:
        return 'Other'

df['SIC_Desc'] = df.apply(map_company,axis=1)

这是不正确的,因为它是改变每一个项目为“其他”,所以很明显我的语法是错误的。有没有人能帮我简化一下我想重新标注的这个专栏? 谢谢


Tags: inmapdfreturndesccompanyrowelif
2条回答

下面是一个使用reversed dictionary的选项。你知道吗

代码

import pandas as pd


# Sample DataFrame
s = pd.Series(["gauze", "opthal", "tape", "surgical", "eye", "spectacles", 
               "glasses",  "optometers", "bandages", "cotton", "glue"])
df = pd.DataFrame({"SIC_Desc": s})
df

enter image description here

LOOKUP = {
    "Eyewear": ["eye", "glasses", "opthal", "spectacles", "optometers"],
    "First Aid": ["cotton", "bandages", "gauze", "tape"],
    "Surgical": ["surgical"],
    "Dental": ["dental", "denture"],
    "Mobility": ["wheelchairs", "walkers", "braces", "crutches", "ortho"],
}

REVERSE_LOOKUP = {v:k for k, lst in LOOKUP.items() for v in lst}

def map_company(row):
    company = row["SIC_Desc"].lower()
    return REVERSE_LOOKUP.get(company, "Other")


df["SIC_Desc"] = df.apply(map_company, axis=1)
df

enter image description here


细节

我们定义了一个LOOKUP字典,它分别包含(key,value)对预期输出和关联词。注意,这些值是小写的,以简化搜索。然后我们使用反向字典来自动反转键值对并提高搜索性能,例如:

>>> REVERSE_LOOKUP
{'bandages': 'First Aid',
 'cotton': 'First Aid',
 'eye': 'Eyewear',
 'gauze': 'First Aid',
 ...}

请注意,这些引用字典是在映射函数外部创建的,以避免为每次调用map_company()重新生成字典。最后,映射函数通过调用.get()使用反向字典快速返回所需的输出,如果找不到条目,该方法将返回默认参数"Other"。你知道吗

请参阅@Flynsee的有见地的答案来解释代码中发生了什么。与一堆条件语句相比,代码更简洁。你知道吗

好处

因为我们已经使用了字典,所以与使用in的O(n)复杂度相比,搜索时间应该相对较快。此外,主LOOKUP字典是可调整的,不需要为新条目手动实现广泛的条件语句。你知道吗

没有数据集的确切内容很难回答,但我可以看出一个错误。根据你的描述,看来你看错了。你希望其中一个词出现在你的公司描述中,所以应该是这样的:

if any(test in company for test in ['Eye', 'glasses', 'opthal', 'spectacles', 'optometers'])

但是,您可能会遇到案例问题,因此我建议:

company = row['SIC_Desc'].lower()
if any(test.lower() in company for test in ['Eye', 'glasses', 'opthal', 'spectacles', 'optometers']):
    return 'Eyewear'

您还需要确保company是一个字符串,'SIC_Desc'是一个正确的列名。你知道吗

最终,您的函数将如下所示:

def is_match(company,names):
    return any(name in company for name in names)

def map_company(row):
    company = row['SIC_Desc'].lower()
    if 'surgical' in company:
         return 'Surgical'
    elif is_match(company,['eye','glasses','opthal','spectacles','optometers']):
        return 'Eyewear'
    elif is_match(company,['cotton', 'bandages', 'gauze', 'tape']):
        return 'First Aid'
    else:
        return 'Other'

相关问题 更多 >