Pandas是基于Numpy的一种工具,它提供了高性能和高可用性的数据结构,以用于解决数据分析问题,纳入了大量的库和一些标准的数据模型,提供了可用于高效操作大型数据集的工具,是使python成为强大而高效的数据分析工具的重要因素之一。
Pandas可以做到读取数据中的数据、读取文件中的数据、数据存储、数据排序、数据统计、数据可视化等功能,而且Pandas兼容所有python的数据类型;
额外支持两种数据结构:
Series是一种类似于一维数组的对象,它由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。
创建方法: s=pd.Series(data,index=index)
data:可以是python列表、标量值 、python字典、ndarray、其他函数;
index:如果没有传递索引值,则默认为np.arange(n)
通过标量创建的系列,标量值将重复匹配指定的索引;
index参数为Series指定了索引标签,不指定的话默认是以0开始的连续递增的整数。
import pandas as pd
ser1=pd.Series(25,index=['a','b','c','d'])
print(ser1)
a 25
b 25
c 25
d 25
dtype: int64
Series也可以通过字典创建:
如果指定索引,则将按指定索引的顺序排列;
import pandas as pd
d={'b':1,'c':4,'a':3}
ser1=pd.Series(d)
print(ser1)
b 1
c 4
a 3
dtype: int64
如果指定的索引值在字典中不存在,则会用NaN(Not a Number)替代,在pandas中用来表示缺失值。
import pandas as pd
d={'b':1,'c':4,'a':3}
ser1=pd.Series(d,index=['a','b','c','d'])
print(ser1)
a 3.0
b 1.0
c 4.0
d NaN
dtype: float64
和通过字典创建不一样,通过ndarray创建序列,如果指定索引,索引长度必须和ndarray指定的数据长度相等。
import numpy as np
import pandas as pd
ser1=pd.Series(np.random.randn(4),index=['a','b','c','d'])
print(ser1)
a -1.577699
b 1.130673
c -0.581641
d -0.219708
dtype: float64
Series还可以通过列表创建,和通过ndarray创建一样,如果指定索引长度,索引长度和列表长度必须相等。
import pandas as pd
ser1=pd.Series([1,2,3,4],index=['a','b','c','d'])
print(ser1)
a 1
b 2
c 3
d 4
dtype: int64
我们可以通过位置和索引标签两种方式进行访问。
这种访问方式类似列表或者字符串的访问,可以访问一个元素,也可以访问数据片段。
import pandas as pd
ser1=pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
print(ser1[0]) # 访问第1个元素1
print(ser1[:3]) # 检索系列中的前三个元素1,2,3
print(ser1[-3:]) # 检索系列中的最后三个元素3,4,5
1
a 1
b 2
c 3
dtype: int64
c 3
d 4
e 5
dtype: int64
Series就像一个固定大小的字典,可以通过索引标签获取和设置值。
import pandas as pd
ser1=pd.Series([1,2,3,4],index=['a','b','c','d'])
print(ser1['b']) # 结果是2
print(ser1[['a','c','d']]) # 获取索引a,c,d对应值
print(ser1['a':'c']) # 获取索引a,b,c的值
2
a 1
c 3
d 4
dtype: int64
a 1
b 2
c 3
dtype: int64
从上例第六行我们可以看到,使用索引标签访问Series数据片段的时候,冒号后面的位置也包括在内,而使用位置访问是不包含冒号后面的最后一个值的。
当两个Series对象进行运算的时候需要注意类型对其操作规则。
从上例运行结果可以看出,Series的运算是按照索引标签对其的,如果一个索引标签在另外一个Series中不存在,结果返回缺失值NaN,这样处理的好处就是不用去考虑数据的位置,而只需要关心索引标签就可以了。
数据框(DataFrame)是二维数据结构,即数据以行和列的表格形式排列。
可以把DataFrame看成是共享同一个index索引的series集合。
从表中可以看出,DataFrame既有行索引也有列索引。
在这里解释下axis的作用,axis即轴,用来为超过一维数组定义的属性,二维数据拥有两个轴,第0轴沿着行的方向垂直向下,第1轴沿着列的方向水平延伸。
DataFrame可以由一维ndarray、二维ndarray、列表、字典、元组或Series构成的字典创建,也可以由DataFrame创建,接下来介绍DataFrame创建函数。
通过单个列表和二维列表创建DataFrame,如果不指定行和列索引标签,默认都从0开始编号。
import pandas as pd
data=[1,3,5,7,9]
df=pd.DataFrame(data)
print(df)
0
0 1
1 3
2 5
3 7
4 9
import pandas as pd
data=[['李军',19],['赵海',18],['张强',20]]
df=pd.DataFrame(data,columns=['Name','Age'])
print(df)
Name Age
0 李军 19
1 赵海 18
2 张强 20
import pandas as pd
data={'Name':['李军','赵海','张强'],'Age':[19,18,20]}
df=pd.DataFrame(data)
print(df)
Name Age
0 李军 19
1 赵海 18
2 张强 20
import pandas as pd
d={'Name':pd.Series(['李军','赵海','张强'],index=['a','b','c']),'Age':pd.Series([19,18,20,21],index=['a','b','c','d'])}
df=pd.DataFrame(d)
print(df)
Name Age
a 李军 19
b 赵海 18
c 张强 20
d NaN 21
从上面两个实例可以看出,如果指定索引值,则将按指定索引的顺序排列;如果指定的索引在字典中不存在,则会用NaN替代,在pandas中用来表示缺失值。
还需要注意的是DataFrame的index值一旦赋值后就不能再赋为其他值。
下表列出了DataFrame基本的属性和方法,比如T属性可以实现转置的操作,下面通过一个实例演示。
属性或方法 | 描述 |
---|---|
T | 转置行和列 |
axes | 返回一个行轴标签和列轴标签的列表 |
dtypes | 返回此对象中的数据类型(dtypes) |
empty | 如果 DataFrame完全为空,则返回为True |
ndim | 返回维度大小 |
shape | 返回表示 DataFrame的维度的元组 |
size | DataFrame中的元素数 |
values | DataFrame中的元素(Numpy的二维数组形式) |
head() | 返回开头前n行 |
tail() | 返回最后n行 |
columns | 返回所有列名的列表 |
index | 返回行轴标签(索引)的列表 |
我们通过DataFrame的read_csv方法从csv文件读取数据,然后通过T属性将DataFrame的数据实现行列交换。
import pandas as pd
df=pd.read_csv('scores2.csv') # scores2.csv是成绩信息
print(df.T) # DataFrame的转置,实现行和列的交换
0 1 2 3
StuNo 2001 2002 2003 2004
name 李军 张强 赵海 张三
java 100 95 54 89
python 100 54 76 78
C 78 75 80 86
要选择DataFrame的列 ,可以通过在[]添加列标签完成,比如要访问first列就可以使用df[‘first’]。
import pandas as pd
d={'first':pd.Series([21,12,14],index=['a','b','c']),
'second':pd.Series([10,20,30,40],index=['a','b','c','d'])}
df=pd.DataFrame(d)
print(df['first']) # 选择'first'列
a 21.0
b 12.0
c 14.0
d NaN
Name: first, dtype: float64
从这个例子可以看出,first列数据中没有d行的数据,输出first列也会输出标签d,只是对应的值是NaN。
创建好DataFrame后,可以根据需要增加列,可以通过Series添加新列,也可以通过已存在的列添加新列;
比如这个例子中,我们把A列和B列数据相加后得到D列,和Series一样,DataFrame也是按索引标签对齐的,D中没有行标签d,因此值为NaN。
import pandas as pd
data={'A':pd.Series([10,20,30],index=['a','b','c']),
'B':pd.Series([1,3,5,7],index=['a','b','c','d'])}
df=pd.DataFrame(data)
print('通过Series添加新列:')
df['C']=pd.Series([2,4,6],index=['a','b','c'])
print(df)
print('通过已存在的列添加新列:')
df['D']=df['A']+df['B']
print(df)
通过Series添加新列:
A B C
a 10.0 1 2.0
b 20.0 3 4.0
c 30.0 5 6.0
d NaN 7 NaN
通过已存在的列添加新列:
A B C D
a 10.0 1 2.0 11.0
b 20.0 3 4.0 23.0
c 30.0 5 6.0 35.0
d NaN 7 NaN NaN
当某些列我不需要的时候,可以通过del或者pop方法删除。
import pandas as pd
data ={'A': pd.Series([11,12,13],index=['a','b','c']),
'B': pd.Series([21,22,23,24],index=['a','b', 'c','d']),
'C': pd.Series([10,20,30],index=['a','b','c'])}
df=pd.DataFrame(data)
# 使用DEL删除功能
del df['A'] # 删除A列
# 使用POP删除功能
df.pop('B') # 删除B列
print(df)
C
a 10.0
b 20.0
c 30.0
d NaN
选取行有两种方法完成,loc和iloc方法,他们的区别在于:
通过将标签传递给loc()函数来选择行:
import pandas as pd
d ={'A': pd.Series([10,20,30],index=['a','b','c']),
'B': pd.Series([1,2,3,4],index=['a','b', 'c','d'])}
df=pd.DataFrame(d)
print(df.loc['b'])
A 20.0
B 2.0
Name: b, dtype: float64
通过将行号传递给iloc()函数来选择行:
import pandas as pd
d ={'A': pd.Series([10,20,30],index=['a','b','c']),
'B': pd.Series([1,2,3,4],index=['a','b', 'c','d'])}
df=pd.DataFrame(d)
print(df.iloc[2]) # 注意行号是0开始,所以实际是第3行
A 30.0
B 3.0
Name: c, dtype: float64
也可以进行行切片,使用运算符选择多行。
需要注意的就是,用loc方法访问的时候,”a:c”是包含c的,iloc的1:3是不包含3的。
import pandas as pd
d ={'A': pd.Series([10,20,30],index=['a','b','c']),
'B': pd.Series([1,2,3,4],index=['a','b', 'c','d'])}
df=pd.DataFrame(d)
df.loc['a':'c','A'],df.iloc[0:2,1:3]
(a 10.0
b 20.0
c 30.0
Name: A, dtype: float64,
B
a 1
b 2)
可以使用append方法为DataFrame添加行,请看实例。
import pandas as pd
df=pd.DataFrame([[10,20],[30,40]],columns=['a','b'])
df1=pd.DataFrame([[50,60],[70,80]],columns=['a','b'])
df=df.append(df1)
print(df)
a b
0 10 20
1 30 40
0 50 60
1 70 80
从运行结果可以看出添加新行后,行索引并没有顺序增加,可以通过reset_index方法实现重新设置索引。
import pandas as pd
df=pd.DataFrame([[10,20],[30,40]],columns=['a','b'])
df1=pd.DataFrame([[50,60],[70,80]],columns=['a','b'])
df=df.append(df1)
df.reset_index(drop=True,inplace=True)
print(df)
a b
0 10 20
1 30 40
2 50 60
3 70 80
当某些行的数据不需要后,可以使用索引标签从DataFrame中删除行;如果标签重复,则会删除多行。
import pandas as pd
df=pd.DataFrame([[10,20],[30,40]],columns = ['a','b'])
df1=pd.DataFrame([[50,60],[70,80]],columns = ['a','b'])
df=df.append(df1)
print (df)
print('删除行标签为0的行')
df=df.drop(0)
print(df)
a b
0 10 20
1 30 40
0 50 60
1 70 80
删除行标签为0的行
a b
1 30 40
1 70 80