2016-02-27 131 views
0

我有一個數據幀:比較列值

import pandas as pd 
import numpy as np 

df = pd.DataFrame([['M',2014,'Seth',5], 
     ['M',2014,'Spencer',5], 
     ['M',2014,'Tyce',5], 
     ['F',2014,'Seth',25], 
     ['F',2014,'Spencer',23]],columns =['sex','year','name','number']) 

print df 

我想找到最性別曖昧的名字在2014年我曾嘗試過很多方法,但都沒有任何運氣然而。

+0

我想找到最性別曖昧的名字在2014年,上述數據幀僅僅是一個非常大的數據幀的一部分。 – Fungie

回答

0

注:我在回答結束時寫了一個函數,但我決定逐個部分地運行代碼,以便更好地理解。


獲取性別不明確的名稱

首先,你會想要得到的性別不明確的名稱列表。我會建議使用集合交集:

>>> male_names = df[df.sex == "M"].name 
>>> female_names = df[df.sex == "F"].name 
>>> gender_ambiguous_names = list(set(male_names).intersection(set(female_names))) 

現在,你想實際子集數據顯示,2014年只有性別曖昧的名字,您可能需要使用會員的條件和鏈布爾條件一個班輪:

>>> gender_ambiguous_data_2014 = df[(df.name.isin(gender_ambiguous_names)) & (df.year == 2014)] 

彙總數據

現在你有這樣的gender_ambiguous_data_2014

>>> gender_ambiguous_data_2014 

    sex year  name number 
0 M 2014  Seth  5 
1 M 2014 Spencer  5 
3 F 2014  Seth  25 
4 F 2014 Spencer  23 

然後你只需按號碼彙總:

>>> gender_ambiguous_data_2014.groupby('name').number.sum() 

name 
Seth  30 
Spencer 28 
Name: number, dtype: int64 

提取姓名(或名稱)

現在,你想要的最後一件事是得到最高數名。但實際上你可能會有性別歧義的名字,總數相同。我們應該在前面的結果應用到一個新的變量gender_ambiguous_numbers_2014並使用它:

>>> gender_ambiguous_numbers_2014 = gender_ambiguous_data_2014.groupby('name').number.sum() 
>>> # get the max and find the list of names: 
>>> gender_ambiguous_max_2014 = gender_ambiguous_numbers_2014[gender_ambiguous_numbers_2014 == gender_ambiguous_numbers_2014.max()] 

現在你會得到這樣的:

>>> gender_ambiguous_max_2014 

name 
Seth 30 
Name: number, dtype: int64 

酷,讓我們提取目錄名稱呢!

>>> gender_ambiguous_max_2014.index 
Index([u'Seth'], dtype='object') 

等等,這是什麼類型的? (提示:這是pandas.core.index.Index

沒問題,只要申請表脅迫:

>>> list(gender_ambiguous_max_2014.index) 
['Seth'] 

讓我們寫這一個功能!

因此,在這種情況下,我們的名單隻有元素。但是也許我們希望編寫一個函數來爲唯一的競爭者返回一個字符串,或者如果某些性別歧義名稱在該年的總數相同,則返回一個字符串列表。

在下面的包裝函數,我簡寫我的變量名與ga縮短代碼。當然,這是假定數據集與您顯示的格式相同,並且被命名爲df。如果它被命名,則只需相應地更改df

def get_most_popular_gender_ambiguous_name(year): 
    """Get the gender ambiguous name with the most numbers in a certain year. 

    Returns: 
     a string, or a list of strings 

    Note: 
     'gender_ambiguous' will be abbreviated as 'ga' 
    """ 
    # get the gender ambiguous names 
    male_names = df[df.sex == "M"].name 
    female_names = df[df.sex == "F"].name 
    ga_names = list(set(male_names).intersection(set(female_names))) 
    # filter by year 
    ga_data = df[(df.name.isin(ga_names)) & (df.year == year)] 
    # aggregate to get total numbers 
    ga_total_numbers = ga_data.groupby('name').number.sum() 
    # find the max number 
    ga_max_number = ga_total_numbers.max() 
    # subset the Series to only those that have max numbers 
    ga_max_data = ga_total_numbers[ 
     ga_total_numbers == ga_max_number 
    ] 
    # get the index (the names) for those satisfying the conditions 
    most_popular_ga_names = list(ga_max_data.index) # list coercion 
    # if list only contains one element, return the only element 
    if len(most_popular_ga_names) == 1: 
     return most_popular_ga_names[0] 
    return most_popular_ga_names 

現在,調用這個函數是因爲它得到一樣簡單:

>>> get_most_popular_gender_ambiguous_name(2014) # assuming df is dataframe var name 
'Seth' 
0

不知道你所說的「最性別ambigious」是什麼意思,但你可以從這個

>>> dfy = (df.year == 2014) 
>>> dfF = df[(df.sex == 'F') & dfy][['name', 'number']] 
>>> dfM = df[(df.sex == 'M') & dfy][['name', 'number']] 
>>> pd.merge(dfF, dfM, on=['name']) 
     name number_x number_y 
0  Seth  25   5 
1 Spencer  23   5 

如果你只想與當時的最高總數的名字開始:

>>> dfT = pd.merge(dfF, dfM, on=['name']) 
>>> dfT 
     name number_x number_y 
0  Seth  25   5 
1 Spencer  23   5 
>>> dfT['total'] = dfT['number_x'] + dfT['number_y'] 
>>> dfT.sort_values('total', ascending=False).head(1) 
    name number_x number_y total 
0 Seth  25   5  30 
+0

上面的代碼does not工作,但生病解釋更多的問題,我需要找到2014年的男性和女性的數量最高的名稱。 – Fungie

+0

什麼是「男性和女性的最高數量」?你的意思是男性和女性的總數?然後'df [df.year == 2014] .groupby(['name'])['number']。sum()'會做 –

+0

不,我不想這樣做。例如,帕特既是男性又是女性的名字。我想找到具有最多男性和女性 – Fungie