2017-09-15 58 views
1

我是一名新的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) 

這是不正確的,但因爲它是不斷變化的每一個項目爲「其他」,這麼清楚我的語法是錯誤的。有人可以幫我簡化這個專欄,我想重新標記嗎? 謝謝

+0

已驗證將進入公司的價值? –

+0

爲什麼不使用調試器?調試器是你的朋友,藉機學習使用一個! – donkopotamus

+0

您還可以發佈您正在使用的數據集嗎? – WhatsYourIdea

回答

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' 
+0

@ Chinny84噢是的確的!感謝您注意這一點。編輯:我修復了它 – Flynsee

+0

所以你會通過編寫df ['SIC_Desc'] = df.apply(map_company,axis = 1)來完成代碼?我試過這個,它仍然把所有的行列爲「其他」 – afzaaldeveloper1

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字典是適應性和解放的手動實施廣泛的條件語句新條目。