将列表简化为类别

时间:2017-09-15 02:39:40

标签: python

我是一名新的Python开发人员,想知道是否有人可以帮助我。我有一个数据集,其中有一列描述了公司类型。我注意到该柱具有例如外科手术,列出的手术。它列出了眼镜,眼镜和验光。因此,我不想在此专栏中有一个巨大的列表,我只想简单地说这个类别,如果你找到一个包含" eye," "眼镜"或者" 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)

这不正确,因为它正在将每个项目更改为"其他,"很明显我的语法错了。有人可以帮我简化这个我想重新考虑的专栏吗? 谢谢

2 个答案:

答案 0 :(得分:4)

如果没有数据集的确切内容,很难回答,但我可以看到一个错误。根据你的描述,你似乎正在以错误的方式看待这个。您希望其中一个词出现在您的公司描述中,因此它应该如下所示:

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'

您还需要确保公司是一个字符串和' 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'

答案 1 :(得分:0)

以下是使用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字典。注意,值为小写以简化搜索。然后我们使用反向字典自动反转键值对并提高搜索性能,例如:

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

请注意,这些引用词典是在映射函数之外创建的,以避免为每次调用map_company()重建字典。最后,映射函数通过调用.get()使用反向字典快速返回所需的输出,如果没有找到条目,则返回默认参数"Other"

请参阅@ Flynsee的深刻答案,了解代码中发生的事情。与一系列条件陈述相比,代码更清晰。

<强>优势

由于我们使用了字典,搜索时间应该相对较快,O(1)与使用in的O(n)复杂度相比较。此外,主LOOKUP字典可以自适应并从手动实现新条目的扩展条件语句中解放出来。