2016-05-01 94 views
1

我想通過使用兩列中的值逐行遍歷DataFrame來生成Series。事情是這樣的:熊貓函數用於從數據幀生成序列

race_cats = ('White', 'Black', 'Hispanic', 'Other') 
def raceParse(row): 
    if row.hispan != 'Not Hispanic': 
     return 'Hispanic' 
    elif row.race == 'White': 
     return 'White' 
    elif row.race == 'Black/Negro': 
     return 'Black' 
    else: 
     return 'Other' 
df['race4'] = df.map(lambda r: raceParse(r)).astype('category', ordered=False, categories=race_cats) 

這不起作用,很明顯,作爲DataFrame沒有map方法。 applyapplymap工作元素明智,不行。什麼是最好的方法來做到這一點?

+0

你可以添加你的'DataFrame'(5,6行)的樣本? – jezrael

+0

apply可以工作row-wise('df.apply(raceParse,axis = 1'),但這可能不是最好的方式(適用不是很快)。我同意樣本會很好。 – ayhan

回答

3

可以實現使用loc您想要的結果如下:

# Sample data. 
df = pd.DataFrame({'hispan': ['Not Hispanic', 'Not Hispanic', 'Hispanic'], 'race': ['White', 'Black', 'Other']}) 

>>> df 
     hispan race 
0 Not Hispanic White 
1 Not Hispanic Black 
2  Hispanic Other 

df['race4'] = 'Other' 
df.loc[df.race == 'Black', 'race4'] = 'Black' 
df.loc[df.race == 'White', 'race4'] = 'White' 
df.loc[~df.hispan.isin(['Not Hispanic']), 'race4'] = 'Hispanic' 

>>> df 
     hispan race  race4 
0 Not Hispanic White  White 
1 Not Hispanic Black  Black 
2  Hispanic Other Hispanic 

然後,您可以轉換列categoricals,如果這是你的願望:

df['race4'] = pd.Categorical(df.race4, categories=['White', 'Black', 'Hispanic', 'Other']) 

注意的順序loc分配很重要。它相當於您的if row.hispan != 'Not Hispanic': ... elif結構。通過最後一次對西班牙裔進行測試,它優先於race列。

我相信上面的回覆是你想要的。根據你的要求,有一個iterrows方法:

def race_parse(row): 
    if row.hispan != 'Not Hispanic': 
     return 'Hispanic' 
    elif row.race == 'White': 
     return 'White' 
    elif row.race == 'Black/Negro': 
     return 'Black' 
    else: 
     return 'Other' 

df['race4'] = [race_parse(row) for _, row in df.iterrows()] 
+0

我試過在一個測試數據集上,它在1.0k數據集上需要1.05ms而在187ms上應用 – ayhan

+0

這是完美的,我嘗試了兩種方法(一種語法錯誤意味着我認爲原來的方法不起作用),但我很好奇,爲什麼'iterrows'方法的速度太慢了,我的數據集只有大約1百萬行;我在大約四五分鐘後放棄了它,而.loc方法或多或少地完成了,是否僅僅是在Pandas之間切換數據結構和標準的Python列表? – futuraprime