Pandas数据帧按3列和标准搜索

时间:2016-11-21 23:37:57

标签: python sorting pandas dataframe

我有来自美国的大熊猫dataframe人口普查数据。列包括STNAME(州名)CTYNAME(县名)和按年份在人口普查报告中收集的许多不同数据列。

我正在寻找人口最多的3个州,仅包括每个州人口最多的3个县。

这是我当前的代码,它稍微调整了原始数据帧,并且只包含与问题相关的内容:

def answer():
    census_df50 = census_df[census_df['SUMLEV'] == 50]
    columns = ['STNAME', 'CTYNAME', 'CENSUS2010POP']
    c = census_df50[columns]
    return c
print(answer())

以下是终端中打印的数据框的示例:

     STNAME             CTYNAME  CENSUS2010POP
1       Alabama      Autauga County          54571
2       Alabama      Baldwin County         182265
3       Alabama      Barbour County          27457
4       Alabama         Bibb County          22915
5       Alabama       Blount County          57322
6       Alabama      Bullock County          10914
7       Alabama       Butler County          20947
8       Alabama      Calhoun County         118572

按国家/地区的字母顺序列出,所以这只按县名显示阿拉巴马州的人口普查数据,但数据框中有超过3000行(每个县有一行,州有多个条目)

我的方法是编写一个函数,根据CTYNAME的{​​{1}}值(一个代表2010年人口的整数)找到CENSUS2016POP中的前3个县,列STNAME中的每个州}。然后让函数按照这个标准将名称作为前3个状态的字符串返回。然而,相当失去了如何实现这一目标。

我很确定我应该尝试使用这些功能.groupby().set_index().nlargest()的组合。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

由于您没有提供任何样本数据,请参阅以下内容:

STNAME,CTYNAME,POPULATION
A,A1,100
A,A2,20
A,A3,30
A,A4,40
B,B1,10
B,B2,2
B,B3,30
B,B4,40
C,C1,100
C,C2,20
C,C3,300
C,C4,40
D,D1,10
D,D2,20
D,D3,30
D,D4,40

In [1]: df = pd.read_clipboard(sep=',')

这是实现预期结果的一种方式,可能更简单,但我无法进一步减少它:

In [2]: df.ix[df['STNAME'].isin(df.groupby('STNAME')['POPULATION'].sum().nlargest(3).index)].groupby(['STNAME','CTYNAME']).sum()['POPULATION'].groupby(level=0, group_keys=False).nlargest(3)

要分解:

# Find the first STNAME Groups
In [3]: largest_states = df.groupby('STNAME')['POPULATION'].sum().nlargest(3).index
        largest_states

Out[3]: Index(['C', 'A', 'D'], dtype='object', name='STNAME')

在这些上过滤df:

In [4]: df2 = df.ix[df['STNAME'].isin(df.groupby('STNAME')['POPULATION'].sum().nlargest(3).index)]

然后找到前三个:

In [5]: df2.groupby(['STNAME','CTYNAME']).sum()['POPULATION'].groupby(level=0, group_keys=False).nlargest(3)

Out[5]:
STNAME  CTYNAME
A       A1         100
        A4          40
        A3          30
C       C3         300
        C1         100
        C4          40
D       D4          40
        D3          30
        D2          20
Name: POPULATION, dtype: int64

<强>更新

如果您希望按州人口排序,请按以下顺序进行排序:

In[6]: df2 = df.groupby(['STNAME','CTYNAME']).sum()['POPULATION'].groupby(level=0, group_keys=False).nlargest(3)

       df2.ix[df.groupby('STNAME')['POPULATION'].sum().nlargest(3).index]

Out[6]:
STNAME  CTYNAME
C       C3         300
        C1         100
        C4          40
A       A1         100
        A4          40
        A3          30
D       D4          40
        D3          30
        D2          20
Name: POPULATION, dtype: int64