Pandas是基于Numpy的一套数据分析工具,该工具是为了解决数据分析任务而创建的。Pandas纳入了大量标准的数据模型,提供了高效地操作大型数据集所需的工具。Pandas提供了大量能使我们快速便捷地处理数据的函数和方法。 它是使Python 成为强大而高效的数据分析环境的重要因素之一
pandas数据类型及其处理
# Series对象创建
# 使用列表创建Series对象
import pandas as pd
data=pd.Series([4,3,5,6,1])
data
0 4
1 3
2 5
3 6
4 1
dtype: int64
# Series 对象中两个重要的属性 values 和 index
print(data.values)
print(data.index)
[4 3 5 6 1]
RangeIndex(start=0, stop=5, step=1)
# 创建Series对象的时候,指定index
data=pd.Series([5,4,6,3,1],index=['one','two','three','four','five'])
data
one 5
two 4
three 6
four 3
five 1
dtype: int64
# 使用字典创建 Series 对象, 默认将 key 作为 index 属性
population_dict={'bj':3000,'gz':1500,'sh':2800,'sz':1200}
population_series=pd.Series(population_dict)
population_series
bj 3000
gz 1500
sh 2800
sz 1200
dtype: int64
# 使用字典创建Series对象,又指定了index属性值,如果 key不存在,则值为NaN
sub_series=pd.Series(population_dict,index=['bj','sh']) #如果存在取交集
sub_series
bj 3000
sh 2800
dtype: int64
sub_series=pd.Series(population_dict,index=['bj','xa']) #如果不存在则值为 NaN
sub_series
bj 3000.0
xa NaN
dtype: float64
# 标量与index属性创建 Series
data=pd.Series(10,index=[4,3,2,5])
data
4 10
3 10
2 10
5 10
dtype: int64
# DataFrame 对象创建
# 将两个series对象作为字典的值,就可以创建一个DataFrame对象。
population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}
area_dict={'beijing':300,'guangzhou':200,'shanghai':180}
import pandas as pd
population_series=pd.Series(population_dict)
area_series=pd.Series(area_dict)
citys=pd.DataFrame({'area':area_series,'population':population_series})
citys
area
population
beijing
300
3000
guangzhou
200
1800
shanghai
180
1200
# 分别查看 DataFrame 对象的 values、 index 和 columns 属性
citys.index
Index(['beijing', 'guangzhou', 'shanghai'], dtype='object')
citys.values
array([[ 300, 3000],
[ 200, 1800],
[ 180, 1200]], dtype=int64)
citys.columns
Index(['area', 'population'], dtype='object')
# 创建 DataFrame 对象, 指定 index 属性
population_dict={'beijing':3000,'guangzhou':1800,'shanghai':1200}
area_dict={'beijing':300,'shanghai':180,'guangzhou':200}
data=pd.DataFrame([area_dict,population_dict],index=['area','population'])
data
beijing
shanghai
guangzhou
area
300
180
200
population
3000
1200
1800
# 创建 DataFrame 对象, 指定列索引 columns
population_series=pd.Series(population_dict)
pd.DataFrame(population_series,columns=['population'])
population
beijing
3000
guangzhou
1800
shanghai
1200
# 使用列表创建 Dataframe 对象
pd.DataFrame([{'a':i,'b':i*2} for i in range(3)])
# 获取 Series 对象的值
# Series 对象的切片、索引
import numpy as np
import pandas as pd
data=pd.Series([4,3,25,2,3],index=list('abcde'))
display('根据 key 获取: ',data['a'])
display('切片获取: ',data['a':'d'])
display('索引获取: ',data.iloc[1])
display('索引切片: ',data[2:4])
# 可以看出Series与ndarray数组都可以通过索引访问元素,Series对象的索引分为位置索引和标签索引。
# 不同之处,标签索引进行切片时候是左闭右闭,而位置索引是左闭右开。
'根据 key 获取: '
4
'切片获取: '
a 4
b 3
c 25
d 2
dtype: int64
'索引获取: '
3
'索引切片: '
c 25
d 2
dtype: int64
data=pd.Series([5,6,7,8],index=[1,2,3,4])
data[1]
5
# 位置索引与标签索引有相同值 1,这时候data[1]就不知道是按哪个来获取,
# 此时要使用loc、iloc。其中loc表示的是标签索引,iloc表示的是位置索引。
data=pd.Series([5,3,2,5,9],index=[1,2,3,4,5])
print(data)
print(data.loc[1])
print(data.iloc[1])
1 5
2 3
3 2
4 5
5 9
dtype: int64
5
3
# 获取 DataFrame 的值
# 1) 选择某一列/某几列
# DataFrame 对象非常容易获取数据集中指定列的数据。只需要在表 df后面的括号中指明要选择的列名即可。
# 如果要获取一列,则只需要传入一个列名;如果是同时选择多列,则传入多个列名即可,多个列名用一个list存放。
# 先创建
import numpy as np
import pandas as pd
data=pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=list('ABCD'))
print(data)
# 获取 DataFrame对象中某一列/某几列
print('获取‘B’ 列: ')
print(data['B'])
print('获取‘A’ ‘C’ 两列: ')
print(data[['A','C']])
# DataFrame 对象获取列,除了传入具体的列名,还可以传入具体列的位置,通过传入位置来获取数据时需要用到iloc方法。
print('获取第 1 列: ')
print(data.iloc[:,0])
print('获取第 1 列和第 3 列: ')
print(data.iloc[:,[0,2]])
# 从上面的示例中可以看到,iloc后的方括号中逗号之前的部分表示要获取的行的位置。只输入一个冒号,
# 不输入任何数值表示获取所有的行;逗号之后的方括号表示要获取的列的位置,列的位置同样也是从0开始计数。
A B C D
a 0 1 2 3
b 4 5 6 7
c 8 9 10 11
获取‘B’ 列:
a 1
b 5
c 9
Name: B, dtype: int32
获取‘A’ ‘C’ 两列:
A C
a 0 2
b 4 6
c 8 10
获取第 1 列:
a 0
b 4
c 8
Name: A, dtype: int32
获取第 1 列和第 3 列:
A C
a 0 2
b 4 6
c 8 10
display(data)
data.iloc[1].iloc[1]
A
B
C
D
a
0
1
2
3
b
4
5
6
7
c
8
9
10
11
5
# 2) 选择连续的某几列
# 我们将通过列名选择数据的方式叫做普通索引,传入列的位置选择数据的方式叫做位置索引。获取连续的某几列,
# 用普通索引和位置索引都可以做到。 因为要获取的列是连续的,所以直接对列进行切片
print('获取 B C D 三列, 使用普通索引获取: ')
print(data.loc[:,'B':'D'])
print('获取 B C D 三列, 使用位置索引获取: ')
print(data.iloc[:,1:4])
# 从上面的示例可以看到, loc 和 iloc 后的方括号中逗号之前的表示选择的行, 当只传入一个冒号时,
# 表示选择所有行,逗号后面表示要选择列。 data.loc[:,'B':'D']表示选择从 B 列开始到 D 列之间
# 的值(包括B列也包括D列),data.iloc[:,1:4]表示选择第2列到第5列之间的值(包括第1列但不包括第5列) 。
获取 B C D 三列, 使用普通索引获取:
B C D
a 1 2 3
b 5 6 7
c 9 10 11
获取 B C D 三列, 使用位置索引获取:
B C D
a 1 2 3
b 5 6 7
c 9 10 11
# 3) 选择某一行/某几行
# 获取行的方式主要有两种,一种是普通索引,即传入具体行索引的名称,需要用到
# loc方法; 另外一种是位置索引, 即传入具体的行数, 需要用到 iloc 方法。
print('获取 a 行,普通索引获取: ')
print(data.loc['a'])
print('获取 a c 行,普通索引获取: ')
print(data.loc[['a','c']])
print('获取第 1 行, 位置索引获取: ')
print(data.iloc[0])
print('获取第 1 行第 3 行, 位置索引获取: ')
print(data.iloc[[0,2]])
获取 a 行,普通索引获取:
A 0
B 1
C 2
D 3
Name: a, dtype: int32
获取 a c 行,普通索引获取:
A B C D
a 0 1 2 3
c 8 9 10 11
获取第 1 行, 位置索引获取:
A 0
B 1
C 2
D 3
Name: a, dtype: int32
获取第 1 行第 3 行, 位置索引获取:
A B C D
a 0 1 2 3
c 8 9 10 11
# 4) 选择连续的某几行
# 选择连续的某几行和选择连续某几列类似, 只要把连续行的位置用一个区间表示即可。
print('选择 a 行 b 行, 使用普通索引: ')
print(data.loc['a':'b'])
print('选择第 1 行 第 2 行, 使用位置索引: ')
print(data.iloc[0:2])
选择 a 行 b 行, 使用普通索引:
A B C D
a 0 1 2 3
b 4 5 6 7
选择第 1 行 第 2 行, 使用位置索引:
A B C D
a 0 1 2 3
b 4 5 6 7
# 同时选择不连续的部分行和部分列
print('同时获取 a c 行, ABD 列, 使用普通索引: ')
print(data.loc[['a','c'],['A','B','D']])
print('同时获取 a c 行, ABD 列, 使用位置索引: ')
print(data.iloc[[0,2],[0,1,3]])
同时获取 a c 行, ABD 列, 使用普通索引:
A B D
a 0 1 3
c 8 9 11
同时获取 a c 行, ABD 列, 使用位置索引:
A B D
a 0 1 3
c 8 9 11
# Series 的方法
# Series对象中有很多常用的方法可以对数据进行各种处理。
# 例如,mean方法可以对某一列数据取平均数,min方法获取最小值,max方法获取最大值,std方法获取标准差。
# 使用 mean、 min、 max、 std 等方法对数据集进行各种运算, 最后对数据集进行排序操作
import pandas as pd
data = pd.DataFrame({
'Name':['zs','lisi','ww'],
'Sno':['1001','1002','1003'],
'Sex':['man','woman','man'],
'Age':[17,18,19],
'Score':[80,97,95]
},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
display('数据集',data)
ages = data['Age']
display('获取数据集中 Age 列的所有',ages)
print('计算 Age 列的平均值: ',ages.mean())
print('计算 Age 列的最大值: ',ages.max())
print('计算 Age 列的最小值: ',ages.min())
print('计算 Age 列的标准差: ',ages.std())
display('对 Age 进行降序排序: ',ages.sort_values(ascending=False))
'数据集'
Sno
Sex
Age
Score
zs
1001
man
17
80
lisi
1002
woman
18
97
ww
1003
man
19
95
'获取数据集中 Age 列的所有'
zs 17
lisi 18
ww 19
Name: Age, dtype: int64
计算 Age 列的平均值: 18.0
计算 Age 列的最大值: 19
计算 Age 列的最小值: 17
计算 Age 列的标准差: 1.0
'对 Age 进行降序排序: '
ww 19
lisi 18
zs 17
Name: Age, dtype: int64
# Series 的条件过滤
# Series 对象也可以像 SQL 语句一样, 通过指定条件来过滤数据。
import pandas as pd
data = pd.DataFrame({
'Name':['zs','lisi','ww'],
'Sno':['1001','1002','1003'],
'Sex':['man','woman','man'],
'Age':[17,18,19],
'Score':[80,97,95]
},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
display('数据集',data)
scores = data['Score']
display('筛选出成绩大于平均值的数据: ',scores[scores>scores.mean()])
'数据集'
Sno
Sex
Age
Score
zs
1001
man
17
80
lisi
1002
woman
18
97
ww
1003
man
19
95
'筛选出成绩大于平均值的数据: '
lisi 97
ww 95
Name: Score, dtype: int64
# DataFrame 的条件过滤
# DataFrame 与 Series 类似, 也可以使用条件进行过滤
import pandas as pd
data = pd.DataFrame({
'Name':['zs','lisi','ww'],
'Sno':['1001','1002','1003'],
'Sex':['man','woman','man'],
'Age':[17,18,19],
'Score':[80,97,95]
},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
display('数据集',data)
scores = data['Score']
display('输出数据中所有成绩大于平均值的记录',data[scores>scores.mean()])
display('获取成绩大于平均值得所有记录,只显示Sno Age Score三列:',data[scores>scores.mean()].loc[:,['Sno','Age','Score']])
'数据集'
Sno
Sex
Age
Score
zs
1001
man
17
80
lisi
1002
woman
18
97
ww
1003
man
19
95
'输出数据中所有成绩大于平均值的记录'
Sno
Sex
Age
Score
lisi
1002
woman
18
97
ww
1003
man
19
95
'获取成绩大于平均值得所有记录,只显示Sno Age Score三列:'
Sno
Age
Score
lisi
1002
18
97
ww
1003
19
95
处理缺失值
# 缺失值就是由某些原因导致部分数据为空,对于为空的这部分数据我们一般有两种处理方式,一
# 种是删除,即把含有缺失值的数据删除;另外一种是填充,即把缺失的那部分数据用某个值代替
# 缺失值查看
# 对缺失值进行处理,首先要把缺失值找出来,也就是查看哪列有缺失值。直接调用 info()方法就会返回每一列的缺失情况
df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
display(df)
df.info()
0
1
2
0
1
2.0
NaN
1
4
NaN
6.0
2
5
6.0
7.0
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 0 3 non-null int64
1 1 2 non-null float64
2 2 2 non-null float64
dtypes: float64(2), int64(1)
memory usage: 204.0 bytes
# Pandas 中缺失值用 NaN 表示,从用 info()方法的结果来看,索引 1 这一列是
# 1 2 non-null float64,表示这一列有2个非空值,而应该是3个非空值,说明这一列有1个空值。
# 还可以用 isnull()方法来判断哪个值是缺失值, 如果是缺失值则返回 True, 如果不是缺失值返回 False
data=pd.Series([3,4,np.nan,1,5,None])
print('isnull()方法判断是否是缺值: ')
print(data.isnull())
print('获取缺值: ')
print(data[data.isnull()])
print('获取非空值')
print(data[data.notnull()])
isnull()方法判断是否是缺值:
0 False
1 False
2 True
3 False
4 False
5 True
dtype: bool
获取缺值:
2 NaN
5 NaN
dtype: float64
获取非空值
0 3.0
1 4.0
3 1.0
4 5.0
dtype: float64
# 缺失值删除
# 缺失值分为两种, 一种是一行中某个字段是缺失值;另一种是一行中的字段全部为缺失值, 即为一个空白行。
# 调用dropna()方法删除缺失值,dropna()方法默认删除含有缺失值的行,也就是只要某一行有缺失值就把这一行删
# 除。如果想按列为单位删除缺失值, 需要传入参数 axis=’columns’
df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
display(df)
print('默认为以行为单位剔除:')
display(df.dropna())
print('以列为单位剔除:')
display(df.dropna(axis='columns'))
0
1
2
0
1
2.0
NaN
1
4
NaN
6.0
2
5
6.0
7.0
默认为以行为单位剔除:
以列为单位剔除:
# 删除空白行
# 如果想删除空白行, 需要给 dropna()方法中传入参数 how=’all’即可, 默认值是 any。
df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
display(df)
print('所有为 nan 时候才剔除:')
display(df.dropna(how='all'))
print('默认情况, 只要有就剔除')
display(df.dropna(how='any'))
0
1
2
0
1
2.0
NaN
1
4
NaN
6.0
2
5
6.0
7.0
所有为 nan 时候才剔除:
0
1
2
0
1
2.0
NaN
1
4
NaN
6.0
2
5
6.0
7.0
默认情况, 只要有就剔除
# 缺失值填充
# 上面介绍了缺失值的删除,但是数据是宝贵的,一般情况下只要数据缺失比例不高(不大于 30%),尽量别删除,而是选择填充。
data=pd.Series([3,4,np.nan,1,5,None])
print('以 0 进行填充:')
display(data.fillna(0))
print('以前一个数进行填充:')
display(data.ffill())
print('以后一个数进行填充:')
display(data.bfill())
print('先按前一个, 再按后一个')
display(data.bfill().ffill())
以 0 进行填充:
0 3.0
1 4.0
2 0.0
3 1.0
4 5.0
5 0.0
dtype: float64
以前一个数进行填充:
0 3.0
1 4.0
2 4.0
3 1.0
4 5.0
5 5.0
dtype: float64
以后一个数进行填充:
0 3.0
1 4.0
2 1.0
3 1.0
4 5.0
5 NaN
dtype: float64
先按前一个, 再按后一个
0 3.0
1 4.0
2 1.0
3 1.0
4 5.0
5 5.0
dtype: float64
# DataFrame 对象缺失值填充
df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
print('使用数值 0 来填充: ')
display(df.fillna(0))
print('使用行的前一个数来填充: ')
display(df.ffill())
print('使用列的后一个数来填充: ')
display(df.bfill(axis=1))
使用数值 0 来填充:
0
1
2
0
1
2.0
0.0
1
4
0.0
6.0
2
5
6.0
7.0
使用行的前一个数来填充:
0
1
2
0
1
2.0
NaN
1
4
2.0
6.0
2
5
6.0
7.0
使用列的后一个数来填充:
0
1
2
0
1.0
2.0
NaN
1
4.0
6.0
6.0
2
5.0
6.0
7.0
# 列的平均值来填充
df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
for i in df.columns:
df[i]=df[i].fillna(np.nanmean(df[i]))
df
0
1
2
0
1
2.0
6.5
1
4
4.0
6.0
2
5
6.0
7.0
拼接
# Series 对象拼接
ser1=pd.Series([1,2,3],index=list('ABC'))
ser2=pd.Series([4,5,6],index=list('DEF'))
display(ser1)
display(ser2)
pd.concat([ser1,ser2])
A 1
B 2
C 3
dtype: int64
D 4
E 5
F 6
dtype: int64
A 1
B 2
C 3
D 4
E 5
F 6
dtype: int64
# 两个 df 对象拼接, 默认找相同的列索引进行合并
def make_df(cols,index):
data={c:[str(c)+str(i) for i in index] for c in cols}
return pd.DataFrame(data,index=index)
df1=make_df('AB',[1,2])
df2=make_df('AB',[3,4])
pd.concat([df1,df2])
A
B
1
A1
B1
2
A2
B2
3
A3
B3
4
A4
B4
# 两个 df 对象拼接, 添加 axis 参数
df1=make_df('AB',[1,2])
df2=make_df('AB',[3,4])
pd.concat([df1,df2],axis=1) #或者 pd.concat([df1,df2],axis='columns')
A
B
A
B
1
A1
B1
NaN
NaN
2
A2
B2
NaN
NaN
3
NaN
NaN
A3
B3
4
NaN
NaN
A4
B4
# 两个 df 对象拼接, 索引重复问题
x=make_df('AB',[1,2])
y=make_df('AB',[1,2])
pd.concat([x,y])
A
B
1
A1
B1
2
A2
B2
1
A1
B1
2
A2
B2
# 两个 df 对象拼接, 解决索引重复问题, 加 keys 属性
x=make_df('AB',[1,2])
y=make_df('AB',[1,2])
pd.concat([x,y],keys=list('xy'))
A
B
x
1
A1
B1
2
A2
B2
y
1
A1
B1
2
A2
B2
# 两个 df 对象拼接, join 内连接做交集
a=make_df('ABC',[1,2])
b=make_df('BCD',[3,4])
pd.concat([a,b],join='inner')
B
C
1
B1
C1
2
B2
C2
3
B3
C3
4
B4
C4
merge的使用
# pandas中的merge和concat类似,但主要是用于两组有key column的数据,统一索引的数据。通常也被用在Database的处理当中。
# 合并时有4种方式 how = ['left', 'right', 'outer', 'inner'],默认值 how='inner'。
# merge 的使用, 默认以 how=’ inner’ 进行合并
left=pd.DataFrame({'key':['k0','k1','k2','k3'],
'A':['A0','A1','A2','A3'],
'B':['B0','B1','B2','B3'],
})
right=pd.DataFrame({'key':['k0','k1','k4','k3'],
'C':['C0','C1','C2','C3'],
'D':['D0','D1','D2','D3'],
})
result=pd.merge(left,right)
display(left)
display(right)
display(result)
key
A
B
0
k0
A0
B0
1
k1
A1
B1
2
k2
A2
B2
3
k3
A3
B3
key
C
D
0
k0
C0
D0
1
k1
C1
D1
2
k4
C2
D2
3
k3
C3
D3
key
A
B
C
D
0
k0
A0
B0
C0
D0
1
k1
A1
B1
C1
D1
2
k3
A3
B3
C3
D3
# merge 的使用, 参数 how=’outer’进行合并
left=pd.DataFrame({'key':['k0','k1','k2','k3'],
'A':['A0','A1','A2','A3'],
'B':['B0','B1','B2','B3'],
})
right=pd.DataFrame({'key':['k0','k1','k4','k3'],
'C':['C0','C1','C2','C3'],
'D':['D0','D1','D2','D3'],
})
display(left)
display(right)
pd.merge(left,right,how='outer')
key
A
B
0
k0
A0
B0
1
k1
A1
B1
2
k2
A2
B2
3
k3
A3
B3
key
C
D
0
k0
C0
D0
1
k1
C1
D1
2
k4
C2
D2
3
k3
C3
D3
key
A
B
C
D
0
k0
A0
B0
C0
D0
1
k1
A1
B1
C1
D1
2
k2
A2
B2
NaN
NaN
3
k3
A3
B3
C3
D3
4
k4
NaN
NaN
C2
D2
# merge的使用, 参数 how=’ left’ 进行合并
left=pd.DataFrame({'key':['k0','k1','k2','k3'],
'A':['A0','A1','A2','A3'],
'B':['B0','B1','B2','B3'],
})
right=pd.DataFrame({'key':['k0','k1','k4','k3'],
'C':['C0','C1','C2','C3'],
'D':['D0','D1','D2','D3'],
})
display(left)
display(right)
pd.merge(left,right,how='left')
key
A
B
0
k0
A0
B0
1
k1
A1
B1
2
k2
A2
B2
3
k3
A3
B3
key
C
D
0
k0
C0
D0
1
k1
C1
D1
2
k4
C2
D2
3
k3
C3
D3
key
A
B
C
D
0
k0
A0
B0
C0
D0
1
k1
A1
B1
C1
D1
2
k2
A2
B2
NaN
NaN
3
k3
A3
B3
C3
D3
# 行索引不同, how=’ right’ 进行合并
left=pd.DataFrame({'key':['k0','k1','k2','k3'],
'A':['A0','A1','A2','A3'],
'B':['B0','B1','B2','B3'],
})
right=pd.DataFrame({'key':['k0','k1','k4','k3'],
'C':['C0','C1','C2','C3'],
'D':['D0','D1','D2','D3'],
})
display(left)
display(right)
pd.merge(left,right,how='right')
key
A
B
0
k0
A0
B0
1
k1
A1
B1
2
k2
A2
B2
3
k3
A3
B3
key
C
D
0
k0
C0
D0
1
k1
C1
D1
2
k4
C2
D2
3
k3
C3
D3
key
A
B
C
D
0
k0
A0
B0
C0
D0
1
k1
A1
B1
C1
D1
2
k4
NaN
NaN
C2
D2
3
k3
A3
B3
C3
D3