2016-02-27 90 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