python高级--美国人口分析(Numpy,Pandas)

下面所用到的数据(可下载)
可点击下载

所用数据文件
state-abbrevs.csv
state-areas.csv
state-population.csv

要求 1、文件导入并查看数据样本

操作 1、导入csv文件

>>> df_abbr = pd.read_csv('./data/state-abbrevs.csv')
>>> df_abbr   #美国各州的名称和缩写

                   state abbreviation
0                Alabama           AL
1                 Alaska           AK
2                Arizona           AZ
3               Arkansas           AR
4             California           CA
5               Colorado           CO
6            Connecticut           CT
7               Delaware           DE
。。。。。
>>> df_areas = pd.read_csv('./data/state-areas.csv')
>>> df_areas   #美国各州面积
                   state  area (sq. mi)
0                Alabama          52423
1                 Alaska         656425
2                Arizona         114006
3               Arkansas          53182
4             California         163707
5               Colorado         104100
6            Connecticut           5544
7               Delaware           1954
。。。。

美国各周及国家各年人口总数

#这里数据较多,我们取前后各5个样本
>>> df_popu = pd.read_csv('./data/state-population.csv')

>>> df_popu.tail() #后5个样本
     state/region     ages  year   population
2539          USA    total  2010  309326295.0
2540          USA  under18  2011   73902222.0
2541          USA    total  2011  311582564.0
2542          USA  under18  2012   73708179.0
2543          USA    total  2012  313873685.0

>>> df_popu.head()  #前5个样本
  state/region     ages  year  population
0           AL  under18  2012   1117489.0
1           AL    total  2012   4817528.0
2           AL  under18  2010   1130966.0
3           AL    total  2010   4785570.0
4           AL  under18  2011   1125763.0

要求2、合并popu与abbrevs两个DataFrame,分别依据state/region列和abbreviation列来合并。

操作 2、根据state/region列和abbreviation列来合并两表

为了保留所有信息,使用外合并 ‘outer’

>>> df1 = pd.merge(df_popu,df_abbr,how='outer',left_on='state/region',right_on='abbreviation')  #根据州名缩写合并人口表和各州名称表
'''
left_on:左边根据哪一列合并
right_on:右边根据哪一列合并
'''
#合并后数据比较多 [2544 rows x 6 columns]
#所以拿出来前五,后五个样本来展示
>>> df1.head()
  state/region     ages  year  population    state abbreviation
0           AL  under18  2012   1117489.0  Alabama           AL
1           AL    total  2012   4817528.0  Alabama           AL
2           AL  under18  2010   1130966.0  Alabama           AL
3           AL    total  2010   4785570.0  Alabama           AL
4           AL  under18  2011   1125763.0  Alabama           AL

>>> df1.tail()
     state/region     ages  year   population state abbreviation
2539          USA    total  2010  309326295.0   NaN          NaN
2540          USA  under18  2011   73902222.0   NaN          NaN
2541          USA    total  2011  311582564.0   NaN          NaN
2542          USA  under18  2012   73708179.0   NaN          NaN
2543          USA    total  2012  313873685.0   NaN          NaN

合并之后因为 州名表中没有USA的缩写,所以合并后的表中 USA 的 state (州名全称) 和 abbreviation(州名缩写列) 列为NaN(空)

要求3、将合并后的df1数据表的空值进行处理

合并之后要对数据进行筛选查看是否有空值

操作 3、处理空值

操作 3-1、筛选空值

'''
isnull()有空值就是True
any(ndarray, axis=None, …)  #看所有的值中有没有True 
df.isnull().any(axis=1)  #来判断 列 中是否有nan/None,True代表有,False则代表没有
df.isnull().any(axis=0)  #来判断 行 中是否有nan/None,True代表有,False则代表没有
'''
>>> df1.isnull().any()  
state/region    False
ages            False
year            False
population       True     #该列有None或NaN
state            True     #该列有None或NaN
abbreviation     True     #该列有None或NaN
dtype: bool

操作 3-2、删除不需要的列

因为合并是按照两个表的州名进行合并的,美国人口表中有州名缩写,所以就可以将合并后有NaN的abbreviation(州名缩写列) 删除。
操作:删除abbreviation列

df1.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors=’raise’)

'''
labels:要删除的 行/列 的名称
axis:删除数据的方向 (默认为 0 按行删除 ,1 按列删除)
index:删除索引为 index的样本(一行/多行)
columns:删除列名为columns的特征(一列/多列)
'''
>>> df2 = df1.drop(labels='abbreviation',axis=1)   #这两个效果相同
>>> df2 = df1.drop(columns='abbreviation',axis=1)  #这两个效果相同
>>> df2
     state/region     ages  year   population    state
0              AL  under18  2012    1117489.0  Alabama
1              AL    total  2012    4817528.0  Alabama
2              AL  under18  2010    1130966.0  Alabama
3              AL    total  2010    4785570.0  Alabama
4              AL  under18  2011    1125763.0  Alabama
。。。 。。。     。。。     。。。     。。。     。。。
2536          USA    total  2009  306771529.0      NaN
2537          USA  under18  2009   74134167.0      NaN
2538          USA  under18  2010   74119556.0      NaN
2539          USA    total  2010  309326295.0      NaN
2540          USA  under18  2011   73902222.0      NaN
2541          USA    total  2011  311582564.0      NaN
2542          USA  under18  2012   73708179.0      NaN
2543          USA    total  2012  313873685.0      NaN

这样就删除了重复的州名缩写列,新的数据框为 df2

操作 3-3、找到有哪些state/region列对应state列的值为NaN,使用unique()查看非重复值(哪些有州缩写,但是没有州全称的,并去重显示)

利用 isnull().any(axis=1) 分析样本是否为空

>>> df2.isnull().any(axis=1)   #样本为空显示Ture,不为空显示False
0       False
1       False
2       False
。。。。
2540     True
2541     True
2542     True
2543     True

将数据为NaN的样本显示出来,返回的是DataFrame数据,不能使用 unique()

>>> df2[df2.isnull().any(axis=1)]  # 显示样本为Ture的数据
     state/region     ages  year   population state
2448           PR  under18  1990          NaN   NaN
2449           PR    total  1990          NaN   NaN
。。。。
2541          USA    total  2011  311582564.0   NaN
2542          USA  under18  2012   73708179.0   NaN
2543          USA    total  2012  313873685.0   NaN

unique()是Series数据的方法,得到Series数据即可去掉重复数据

>>> df2[df2.isnull().any(axis=1)]['state/region']   #拿到Series数据
2448     PR
2449     PR
2450     PR
。。。
2541    USA
2542    USA
2543    USA

使用Series对象的unique()方法去重

>>> df2[df2.isnull().any(axis=1)]['state/region'].unique()   #去重
array(['PR', 'USA'], dtype=object)

这里得到了‘state’(州全称)为空的州’state/region’(州缩写) 这里需要将这些州的全称补齐

操作 3-4、找到将’state/region’(州缩写) 的全称补齐

1)首先找到 ‘state/region’ 是 ‘PR’ 的样本

>>> df2['state/region']=='PR'  #找到列(州缩写为“PR”的) 返回 True/False (等于的是Ture,不等于的返回False)
0       False
1       False
29      False
        ...
2542    False
2543    False
Name: state/region, Length: 2544, dtype: bool

我们将样本拿出来(将上面为True的拿出来)


>>> df2[df2['state/region']=='PR']
     state/region     ages  year  population state
2448           PR  under18  1990         NaN   NaN
2449           PR    total  1990         NaN   NaN
。。。
2493           PR    total  2011   3686580.0   NaN
2494           PR  under18  2012    841740.0   NaN
2495           PR    total  2012   3651545.0   NaN

注意!
这里不能直接把值设置给DataFrame
要用DataFrame给DataFrame赋值

不能使用
df2[df2['state/region']=='PR']['state'] = 'Puerto Rico'.


正确用法:

>>> temp = df2[df2['state/region']=='PR'].copy()  #拷贝一份新的DataFrame
>>> temp['state'] =  'Puerto Rico'  #在新的DataFrame上面做修改
>>> temp
     state/region     ages  year  population        state
2448           PR  under18  1990         NaN  Puerto Rico
2449           PR    total  1990         NaN  Puerto Rico
2450           PR    total  1991         NaN  Puerto Rico
。。。
2494           PR  under18  2012    841740.0  Puerto Rico
2495           PR    total  2012   3651545.0  Puerto Rico

将修改好的temp赋值给

>>> df2[df2['state/region']=='PR']= temp   #将新的DataFrame赋值给之前的DataFrame
#再次查询州全称是否有空值
>>> df2.isnull().any()
state/region    False
ages            False
year            False
population       True
state            True
dtype: bool

**此时还有州缩写为USA的全称为NaN
按照补全 “ PR ” 的方式 补全” USA “**

>>> # df2[df2['state/region']=='PR']['state'] = 'Puerto Rico'
... temp2 = df2[df2['state/region']=='USA'].copy()
>>> temp2['state'] =  'United States'
>>> temp2
     state/region     ages  year   population          state
2496          USA  under18  1990   64218512.0  United States
2497          USA    total  1990  249622814.0  United States
2498          USA    total  1991  252980942.0  United States
...
2541          USA    total  2011  311582564.0  United States
2542          USA  under18  2012   73708179.0  United States
2543          USA    total  2012  313873685.0  United States

补全后再次查询state是否还有nan值

>>> df2.isnull().any()  
state/region    False
ages            False
year            False
population       True
state           False
dtype: bool

此时state的数据显示都不为空,我们再来处理“population”为空的数据
查看为空值的样本

>>> df2[df2.isnull().any(axis=1)]
     state/region     ages  year  population        state
2448           PR  under18  1990         NaN  Puerto Rico
2449           PR    total  1990         NaN  Puerto Rico
2450           PR    total  1991         NaN  Puerto Rico
。。。
2465           PR  under18  1997         NaN  Puerto Rico
2466           PR    total  1999         NaN  Puerto Rico
2467           PR  under18  1999         NaN  Puerto Rico

这些数据在我们后面的需求中因为用不到,所以我们就可以将这些样本删除
df2.dropna(axis=0, how=’any’, thresh=None, subset=None, inplace=False)
功能:删除空值

'''
axis:删除空值所在的行或列(默认 0,删除空值所在的行,1 删除所在的列)
'''
>>> df3 = df2.dropna()
>>> df3.isnull().any()
state/region    False
ages            False
year            False
population      False
state           False
dtype: bool

现在我们的空值数据已经全部处理完了

要求 4、将各州人口数据df3和面积数据areas合并(外合并)

操作4-1、合并两个数据框

>>> df4 = pd.merge(df3,df_areas,how='outer')
>>> df4
     state/region     ages  year   population          state  area (sq. mi)
0              AL  under18  2012    1117489.0        Alabama        52423.0
1              AL    total  2012    4817528.0        Alabama        52423.0
。。。
2521          USA    total  2011  311582564.0  United States            NaN
2522          USA  under18  2012   73708179.0  United States            NaN
2523          USA    total  2012  313873685.0  United States            NaN

[2524 rows x 6 columns]

合并之后查看是否有空值

>>> df4.isnull().any()
state/region     False
ages             False
year             False
population       False
state            False
area (sq. mi)     True
dtype: bool

查看含有空值的样本,返回True/False

>>> df4.isnull().any(axis=1)  # 查看行中是否有NaN
0       False
1       False
。。。
2522     True
2523     True
Length: 2524, dtype: bool

查看含有空值的样本,返回数据框(DataFrame)

>>> df4[df4.isnull().any(axis=1)]
     state/region     ages  year   population          state  area (sq. mi)
2476          USA  under18  1990   64218512.0  United States            NaN
2477          USA    total  1990  249622814.0  United States            NaN
...
2520          USA  under18  2011   73902222.0  United States            NaN
2521          USA    total  2011  311582564.0  United States            NaN
2522          USA  under18  2012   73708179.0  United States            NaN
2523          USA    total  2012  313873685.0  United States            NaN

可以看出缺失的值是美国国家总面积,因为我们的需求中要不到,所以就可以删除这些样本数据了


>>> df5 = df4.dropna()   #删除掉缺失美国国家面积的样本数据
>>> df5.isnull().any()   #可以看到现在没有了空数据
state/region     False
ages             False
year             False
population       False
state            False
area (sq. mi)    False
dtype: bool

要求 4、找出2010年的各州全民人口数据

df.query(查询语句)

DataFarme.query(expr, inplace=False, **kwargs)

'''
expr:要查询的字符串
&:与
'''
>>> df5.query('year==2010&ages=="total"')
     state/region   ages  year  population                 state  area (sq. mi)
3              AL  total  2010   4785570.0               Alabama        52423.0
91             AK  total  2010    713868.0                Alaska       656425.0
101            AZ  total  2010   6408790.0               Arizona       114006.0
。。。
2394           WI  total  2010   5689060.0             Wisconsin        65503.0
2405           WY  total  2010    564222.0               Wyoming        97818.0
2470           PR  total  2010   3721208.0           Puerto Rico         3515.0

要求 4、对查询结果进行处理,以state列作为新的行索引

DataFrame.set_index(keys,drop=True,append=False,inplace=False,verify_integrity=False)
功能:使用一个或多个现有的索引(行标签)设置DataFrame索引列(用现有的列替换掉默认的索引)

之前的数据框

>>> df5.head()
  state/region     ages  year  population    state  area (sq. mi)
0           AL  under18  2012   1117489.0  Alabama        52423.0
1           AL    total  2012   4817528.0  Alabama        52423.0
2           AL  under18  2010   1130966.0  Alabama        52423.0
3           AL    total  2010   4785570.0  Alabama        52423.0
4           AL  under18  2011   1125763.0  Alabama        52423.0

将之前的“state”替换掉默认的索引的数据框

>>> df6 = df5.set_index('state')
>>> df6.head()
        state/region     ages  year  population  area (sq. mi)
state
Alabama           AL  under18  2012   1117489.0        52423.0
Alabama           AL    total  2012   4817528.0        52423.0
Alabama           AL  under18  2010   1130966.0        52423.0
Alabama           AL    total  2010   4785570.0        52423.0
Alabama           AL  under18  2011   1125763.0        52423.0

要求 5、对新的数据进行排序,并找出人口密度最高的五个州

DataFrame两个特征的计算

DataFrame的两个列相计算,返回计算后的结果和原索引,是一个Series

将两个列(人口和面积)相除,得到人口的密度

>>> density = df6['population']/df6['area (sq. mi)']     #df6的两个列相除,返回相应的索引和值
>>> density.head()
state
Alabama    21.316769
Alabama    91.897221
Alabama    21.573851
Alabama    91.287603
Alabama    21.474601
dtype: float64

排序

density.sort_values(axis=0,ascending=True,inplace=False,kind=’quicksort’,na_position=’last’)

功能:对值进行升序或降序排列

'''
axis:以指定或默认列排序
    默认为0 只有一列数据时可以
    ‘index’ 可以指定索引进行拍戏
ascending:升序或降序(默认为True 升序,False 降序)
na_position:nan的位置
'''
>>> density.sort_values().tail()
state
District of Columbia    8898.897059
District of Columbia    8901.779412
District of Columbia    9112.117647
District of Columbia    9315.102941
District of Columbia    9506.602941
dtype: float64

ascending为True,升序排序,得到密度最大的5个州的人口密度

猜你喜欢

转载自blog.csdn.net/PyRookie/article/details/81533477