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
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
select * from a union select * from b;
#联合查询 :查询的字段名可以不一致,数据类型可以不一致,但是字段的数量必须一一致
concat()
级联 合并
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 |
忽略原来的索引,从新定义新的索引
(解决两表合并是出现行号重复的问题)
In [61]:
pd.concat((user,score),axis=0,join='outer',ignore_index=True)
. . .
设定多层索引的
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 |
使用谁的列名,值是一个序列类型
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()
默认识别两边的同名列
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() 当某一列被设置为行号以后,不参与计算
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 |
将原先制定的行索引恢复成列
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 |
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
In [ ]:
In [ ]:
In [ ]: