jupyter notebook 之 pandas_2

 

 

In [1]:

 

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

多级索引

多级索引主要是用来给excel进行操作的

In [2]:

 

#多级行索引 +  多级列索引
df = pd.DataFrame(np.random.randint(0,150,(8,10)),
            index=pd.MultiIndex.from_product([['初中','高中'],['一次月考','期中','二次月考','期末']]),
            columns=pd.MultiIndex.from_product([['上学期','下学期'],['体育','音乐','计算机','历史','生物']]))

In [3]:

 

df.to_excel('df.xlsx',sheet_name='Sheet2')

In [4]:

 

#多级索引如何取值
# 高中上学期体育的期末考试
df

Out[4]:

    上学期 下学期
    体育 音乐 计算机 历史 生物 体育 音乐 计算机 历史 生物
初中 一次月考 141 148 72 100 111 24 66 80 91 42
期中 25 89 138 125 14 148 20 21 86 34
二次月考 78 141 110 60 41 90 47 48 96 4
期末 37 0 111 122 84 81 38 142 83 33
高中 一次月考 12 27 28 81 62 33 36 132 83 21
期中 50 142 84 130 1 44 121 20 9 80
二次月考 120 16 64 64 80 136 140 105 57 22
期末 100 11 134 95 109 95 23 59 92 86

In [5]:

 

#如果要是取行,那么先把行条去完整了
df.loc['高中','期末']['上学期','体育']

Out[5]:

100

In [6]:

 

df.loc['高中','上学期'].loc['期末','体育']

Out[6]:

100

In [7]:

 

df['上学期','体育']['高中','期末']

Out[7]:

100

索引的堆操作

主要的作用是把Series和DataFrame进行互相转换的

  • stack() 把列索引变为行索引

  • unstack() 把行索引变为列索引

  • stack : 堆

level=-1 表示的是最内存的索引

dropna=True 删除空数据行

In [8]:

 

#把series转变成dataframe
df.loc['高中','期末'].unstack()

Out[8]:

  体育 历史 生物 计算机 音乐
上学期 100 95 109 134 11
下学期 95 92 86 59 23

In [9]:

 

df.loc['高中','期末']

Out[9]:

上学期  体育     100
     音乐      11
     计算机    134
     历史      95
     生物     109
下学期  体育      95
     音乐      23
     计算机     59
     历史      92
     生物      86
Name: (高中, 期末), dtype: int64

In [10]:

 

df.loc['高中','期末'].unstack().stack()

Out[10]:

上学期  体育     100
     历史      95
     生物     109
     计算机    134
     音乐      11
下学期  体育      95
     历史      92
     生物      86
     计算机     59
     音乐      23
dtype: int64

一层索引的Series转变成DataFrame

In [11]:

 

S = pd.Series(data=np.random.randint(0,10,6),index=list('abcdef'))

In [12]:

 

pd.DataFrame(S)

Out[12]:

  0
a 0
b 4
c 8
d 6
e 3
f 4

聚合函数

In [13]:

 

df1 = df.loc['高中','期末'].unstack()

In [14]:

 

df1

Out[14]:

  体育 历史 生物 计算机 音乐
上学期 100 95 109 134 11
下学期 95 92 86 59 23

In [15]:

 

df1.sum()

Out[15]:

体育     195
历史     187
生物     195
计算机    193
音乐      34
dtype: int64

In [16]:

 

df1.max()

Out[16]:

体育     100
历史      95
生物     109
计算机    134
音乐      23
dtype: int64

In [17]:

 

df1.min()

Out[17]:

体育     95
历史     92
生物     86
计算机    59
音乐     11
dtype: int64

In [18]:

 

df1.mean()

Out[18]:

体育     97.5
历史     93.5
生物     97.5
计算机    96.5
音乐     17.0
dtype: float64

方差:

 

∑ni=1(xi−mean)2n∑i=1n(xi−mean)2n

样本方差:

方差:

 

∑ni=1(xi−mean)2n−1∑i=1n(xi−mean)2n−1

In [19]:

 

#方差
df2=df1.T
df2

Out[19]:

  上学期 下学期
体育 100 95
历史 95 92
生物 109 86
计算机 134 59
音乐 11 23

In [20]:

 

df3=df2.iloc[1:]
df3

Out[20]:

  上学期 下学期
历史 95 92
生物 109 86
计算机 134 59
音乐 11 23

In [21]:

 

#在代数中方差除以样本的数量
#pandas中的方差叫做  统计学 中的 样本方差 , 无损计算  n-1 
#会让差异膨胀
df3.var()

Out[21]:

上学期    2844.25
下学期     990.00
dtype: float64

In [22]:

 

mean_ = df3.iloc[:,0].mean()
sum_ = 0
for v in df3.iloc[:,0]:
    sum_ += (v-mean_)**2

In [23]:

 

sum_ / 3

Out[23]:

2844.25

In [24]:

 

np.var(df3.iloc[:,0])

Out[24]:

2133.1875

标准差:

 

∑ni=1(xi−mean)2n⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯√∑i=1n(xi−mean)2n

样本标准差:

 

∑ni=1(xi−mean)2n−1⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯√∑i=1n(xi−mean)2n−1

In [25]:

 

#标准差  在方差的基础上开根
#样本标准差
#一堆数的平均差异
df3.std()

Out[25]:

上学期    53.331510
下学期    31.464265
dtype: float64

In [26]:

 

(sum_ / 3)**0.5

Out[26]:

53.33151038551224

DataFrame的合并

 

select * from a union select * from  b;
#联合查询 :查询的字段名可以不一致,数据类型可以不一致,但是字段的数量必须一一致

concat()

级联 合并

  • objs 要求值是一个序列类型
  • axis=0 连接的方向
  • join='outer' 连接的方式

In [41]:

 

from sqlalchemy import create_engine
import warnings
warnings.filterwarnings('ignore')

In [31]:

 

dbinfo = dict(
    host = 'localhost',
    port = 3306,
    username = 'root',
    password = '123456',
    database = 'python',
    charset = 'utf8'
)
engine=create_engine("mysql+pymysql://{username}:{password}@{host}:{port}/{database}?charset={charset}".format(**dbinfo))

In [45]:

 

user = pd.read_sql('userinfo1',engine)
user

Out[45]:

  id name pwd
0 1 张三 123456
1 2 赵四 123456
2 3 王五 123456
3 4 赵六 123456
4 5 鬼脚七 123456

In [46]:

 

score = pd.read_sql('score',engine)
score

Out[46]:

  id python java
0 1 120.0 13.0
1 2 220.0 23.0
2 3 330.0 34.0
3 4 100.0 0.0
4 1 100.0 0.0
5 2 33.0 0.0
6 2 55.0 0.0
7 3 100.0 0.0

In [55]:

 

#联合 全外连接
#行合并
pd.concat((user,score),axis=0,join='outer')

. . .

In [57]:

 

#列合并
pd.concat((user,score),axis=1,join='inner')

Out[57]:

  id name pwd id python java
0 1 张三 123456 1 120.0 13.0
1 2 赵四 123456 2 220.0 23.0
2 3 王五 123456 3 330.0 34.0
3 4 赵六 123456 4 100.0 0.0
4 5 鬼脚七 123456 1 100.0 0.0

ignore_index

忽略原来的索引,从新定义新的索引

(解决两表合并是出现行号重复的问题)

In [61]:

 

pd.concat((user,score),axis=0,join='outer',ignore_index=True)

. . .

keys

设定多层索引的

In [65]:

 

k=pd.concat((user,score),axis=0,join='outer',keys=['user','score'])
k

Out[65]:

    id java name pwd python
user 0 1 NaN 张三 123456 NaN
1 2 NaN 赵四 123456 NaN
2 3 NaN 王五 123456 NaN
3 4 NaN 赵六 123456 NaN
4 5 NaN 鬼脚七 123456 NaN
score 0 1 13.0 NaN NaN 120.0
1 2 23.0 NaN NaN 220.0
2 3 34.0 NaN NaN 330.0
3 4 0.0 NaN NaN 100.0
4 1 0.0 NaN NaN 100.0
5 2 0.0 NaN NaN 33.0
6 2 0.0 NaN NaN 55.0
7 3 0.0 NaN NaN 100.0

In [70]:

 

k.iloc[0:2]

Out[70]:

    id java name pwd python
user 0 1 NaN 张三 123456 NaN
1 2 NaN 赵四 123456 NaN

join_axes

  • axes : axis 的复数 (轴)

使用谁的列名,值是一个序列类型

In [78]:

 

pd.concat((user,score),axis=0,join='outer',join_axes=[user.columns])

Out[78]:

  id name pwd
0 1 张三 123456
1 2 赵四 123456
2 3 王五 123456
3 4 赵六 123456
4 5 鬼脚七 123456
0 1 NaN NaN
1 2 NaN NaN
2 3 NaN NaN
3 4 NaN NaN
4 1 NaN NaN
5 2 NaN NaN
6 2 NaN NaN
7 3 NaN NaN

换一种思路

In [79]:

 

user.columns

Out[79]:

Index(['id', 'name', 'pwd'], dtype='object')

In [80]:

 

user.values

Out[80]:

array([[1, '张三', '123456'],
       [2, '赵四', '123456'],
       [3, '王五', '123456'],
       [4, '赵六', '123456'],
       [5, '鬼脚七', '123456']], dtype=object)

In [81]:

 

score.values

Out[81]:

array([[  1., 120.,  13.],
       [  2., 220.,  23.],
       [  3., 330.,  34.],
       [  4., 100.,   0.],
       [  1., 100.,   0.],
       [  2.,  33.,   0.],
       [  2.,  55.,   0.],
       [  3., 100.,   0.]])

In [84]:

 

pd.DataFrame(np.concatenate([user.values,score.values]),columns=user.columns)

Out[84]:

  id name pwd
0 1 张三 123456
1 2 赵四 123456
2 3 王五 123456
3 4 赵六 123456
4 5 鬼脚七 123456
5 1 120 13
6 2 220 23
7 3 330 34
8 4 100 0
9 1 100 0
10 2 33 0
11 2 55 0
12 3 100 0

'联表查询',左右合并

pd.merge()

默认识别两边的同名列

  • left : DataFrame
  • right : DataFrame
  • how : {'left', 'right', 'outer', 'inner'}, default 'inner'
  • left_index=True 使用左边DataFrame的行索引作为关联合并的条件
  • right_index=True 使用右边DataFrame的行索引作为关联合并的条件

In [96]:

 

score.loc[score.shape[0]] = [6,20,200]

In [107]:

 

score.columns = ['sid','python','java']

In [108]:

 

display(user,score)
  id name pwd
0 1 张三 123456
1 2 赵四 123456
2 3 王五 123456
3 4 赵六 123456
4 5 鬼脚七 123456
  sid python java
0 1 120.0 13.0
1 2 220.0 23.0
2 3 330.0 34.0
3 4 100.0 0.0
4 1 100.0 0.0
5 2 33.0 0.0
6 2 55.0 0.0
7 3 100.0 0.0
8 6 20.0 200.0

In [110]:

 

pd.merge(user,score,how='outer',left_on='id',right_on='sid')

. . .

指定行号

set_index() 当某一列被设置为行号以后,不参与计算

  • keys 指定那一列作为行号
  • inplace

merge : 合并

In [111]:

 

user

Out[111]:

  id name pwd
0 1 张三 123456
1 2 赵四 123456
2 3 王五 123456
3 4 赵六 123456
4 5 鬼脚七 123456

In [113]:

 

user.set_index(keys='id',inplace=True)

In [115]:

 

score.set_index(keys='sid',inplace=True)

In [124]:

 

pd.merge(user,score,how='outer',left_index=True,right_index=True)

Out[124]:

  name pwd python java
1 张三 123456 120.0 13.0
1 张三 123456 100.0 0.0
2 赵四 123456 220.0 23.0
2 赵四 123456 33.0 0.0
2 赵四 123456 55.0 0.0
3 王五 123456 330.0 34.0
3 王五 123456 100.0 0.0
4 赵六 123456 100.0 0.0
5 鬼脚七 123456 NaN NaN
6 NaN NaN 20.0 200.0

reset_index()

将原先制定的行索引恢复成列

In [126]:

 

user.reset_index(inplace=True)

In [132]:

 

r = pd.merge(user,score,how='outer',left_on='id',right_index=True)

In [138]:

 

r.index = range(r.shape[0])

In [139]:

 

r

Out[139]:

  id name pwd python java
0 1 张三 123456 120.0 13.0
1 1 张三 123456 100.0 0.0
2 2 赵四 123456 220.0 23.0
3 2 赵四 123456 33.0 0.0
4 2 赵四 123456 55.0 0.0
5 3 王五 123456 330.0 34.0
6 3 王五 123456 100.0 0.0
7 4 赵六 123456 100.0 0.0
8 5 鬼脚七 123456 NaN NaN
9 6 NaN NaN 20.0 200.0

suffixes

  • suffies : 后缀
  • 防止非关联列,列名冲突

In [140]:

 

user

. . .

In [145]:

 

score

. . .

In [158]:

 

#select user.name uname,user.pwd upwd,score.name sname,score.pwd spwd from user join  score on user.id = score.id
z = pd.merge(user,score,how='outer',left_on='id',right_on='id',suffixes=('_user', '_score'))
z.head()

Out[158]:

  id name_user pwd_user name_score pwd_score
0 1 张三 123456 120.0 13.0
1 1 张三 123456 100.0 0.0
2 2 赵四 123456 220.0 23.0
3 2 赵四 123456 33.0 0.0
4 2 赵四 123456 55.0 0.0

简单数据分析

In [272]:

 

abb = pd.read_csv('./data/state-abbrevs.csv')
are = pd.read_csv('./data/state-areas.csv')
pop = pd.read_csv('./data/state-population.csv')

In [273]:

 

abb.info(),are.info(),pop.info()

RangeIndex: 51 entries, 0 to 50
Data columns (total 2 columns):
state           51 non-null object
abbreviation    51 non-null object
dtypes: object(2)
memory usage: 896.0+ bytes

RangeIndex: 52 entries, 0 to 51
Data columns (total 2 columns):
state            52 non-null object
area (sq. mi)    52 non-null int64
dtypes: int64(1), object(1)
memory usage: 912.0+ bytes

RangeIndex: 2544 entries, 0 to 2543
Data columns (total 4 columns):
state/region    2544 non-null object
ages            2544 non-null object
year            2544 non-null int64
population      2524 non-null float64
dtypes: float64(1), int64(1), object(2)
memory usage: 79.6+ KB

Out[273]:

(None, None, None)

In [274]:

 

abb.head()

Out[274]:

  state abbreviation
0 Alabama AL
1 Alaska AK
2 Arizona AZ
3 Arkansas AR
4 California CA

In [275]:

 

are.head()

Out[275]:

  state area (sq. mi)
0 Alabama 52423
1 Alaska 656425
2 Arizona 114006
3 Arkansas 53182
4 California 163707

In [276]:

 

pop.head()

Out[276]:

  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

合并

In [277]:

 

abb_pop = pd.merge(pop,abb,left_on='state/region',right_on='abbreviation',how='outer')

删除重复的列

In [278]:

 

abb_pop.drop(labels='abbreviation',axis=1,inplace=True)

检查空缺数据

In [279]:

 

abb_pop.isnull().sum()

Out[279]:

state/region     0
ages             0
year             0
population      20
state           96
dtype: int64

填充州名

In [280]:

 

abb_pop.columns = ['state_region', 'ages', 'year', 'population', 'state']

In [281]:

 

#获取州名为空的行号
state_indexs = abb_pop['state'].isnull()

 

df.unique() 显示唯一值

In [282]:

 

#查找空缺州的州名缩写
abb_pop['state_region'][state_indexs].unique()

Out[282]:

array(['PR', 'USA'], dtype=object)

In [283]:

 

#PR 波多黎各   Puerto Rico
#USA  美利坚   the United States of America
pr_index = abb_pop.query("state_region == 'PR'").index
pr = abb_pop.loc[pr_index]
pr['state'] = 'Puerto Rico'
abb_pop.loc[pr_index] = pr 
usa_index = abb_pop.query("state_region == 'USA'").index
usa = abb_pop.loc[usa_index]
usa['state'] = 'the United States of America'
abb_pop.loc[usa_index] = usa

In [284]:

 

abb_pop.isnull().sum()

Out[284]:

state_region     0
ages             0
year             0
population      20
state            0
dtype: int64

填充人口数据

In [285]:

 

#查看哪个州的人口为空
pop_indexs = abb_pop['population'].isnull()

In [286]:

 

abb_pop['state'][pop_indexs].unique()

Out[286]:

array(['Puerto Rico'], dtype=object)

In [296]:

 

#填补未满18岁
under18_ind = abb_pop.query("state=='Puerto Rico' & ages=='under18' & year<2000").index
under18 = abb_pop.loc[under18_ind]
under18['population'] = 1080000
abb_pop.loc[under18_ind] = under18
total_ind = abb_pop.query("state=='Puerto Rico' & ages=='total' & year<2000").index
total = abb_pop.loc[total_ind]
total['population'] = 3810000
abb_pop.loc[total_ind] = total

合并面积

In [300]:

 

abb_pop_are = pd.merge(abb_pop,are,how='outer')

检查空值

In [301]:

 

abb_pop_are.isnull().sum()

Out[301]:

state_region      0
ages              0
year              0
population        0
state             0
area (sq. mi)    48
dtype: int64

In [302]:

 

abb_pop_are.columns

Out[302]:

Index(['state_region', 'ages', 'year', 'population', 'state', 'area (sq. mi)'], dtype='object')

In [303]:

 

area_indexs = abb_pop_are['area (sq. mi)'].isnull()

In [306]:

 

#那个州的面积为空
abb_pop_are['state'][area_indexs].unique()

Out[306]:

array(['the United States of America'], dtype=object)

In [309]:

 

#获取空缺值的年份
years = abb_pop_are.query("state_region=='USA'")['year'].unique()

In [310]:

 

years

Out[310]:

array([1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
       2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2013, 2009, 2010,
       2011, 2012])

In [317]:

 

for y in years:
    display(abb_pop_are.query("year==%s  & ages=='total' & state_region != 'USA'"%y)['area (sq. mi)'].sum())

. . .

In [327]:

 

#填补面积空缺
usa_are_index = abb_pop_are.query('state_region == "USA"').index
usa_are = abb_pop_are.loc[usa_are_index]
usa_are['area (sq. mi)'] = 3790399.0
abb_pop_are.loc[usa_are_index] = usa_are

找到2012年美国人口的数据信息

In [ ]:

 

找出美国人口最少的3个州&人口最多的三个州

In [ ]:

 

人口密度最高的3个州

In [ ]:

 

你可能感兴趣的:(数据)