下面所用到的数据(可下载)
可点击下载
所用数据文件
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个州的人口密度