Pandas的知识与实践
Pandas与NumPy的主要区别在于:NumPy中的ndarray只能进行数值类型的数据处理,而Pandas是基于NumPy进一步封装的包,并且提供了计算接口,丰富并简化了Numpy的操作,使得Pandas既可以进行数值类型的数据处理,也可以进行非数值类型的数据统计与分析。
Pandas的使用需要结合NumPy才行,所以Pandas安装前要先安装NumPy:
pip install numpy
pip install pandas
Pandas使用前,先将Pandas导入才能继续后续操作:
import pandas as pd
Pandas非常适合许多不同类型的数据,具有异构类型列的表格数据,包含有序和无序时间序列数据,具有行和列标签的任意矩阵数据,以及观察/统计数据集的任何其他形式。实际上,数据根本不需要标记即可放入Pandas数据结构。那么Pandas的数据结构如何?主要有两种主要的数据结构,分别是Series(一维)和DataFrame(二维)。
一维标记的均匀类型数组,类似于定长的有序字典,有Index和value。
它由一组数据和一组与数据相对应的数据标签(索引index)组成。这组数据和索引标签的基础都是一个一维ndarray数组。可将index索引理解为行索引。 Series的表现形式为:索引在左,数据在右。
根据列表生成Series:
>>> import pandas as pd
>>> list = ['a','b','c']
>>> sf = pd.Series(list)
>>> sf
0 a
1 b
2 c
dtype: object
>>> type(sf)
<class 'pandas.core.series.Series'>
>>> sf[1]
'b'
>>>
获取数据和索引:
>>> sf.index
RangeIndex(start=0, stop=3, step=1)
>>> for i in sf.index:
... print(i)
...
0
1
2
>>> sf.values
array(['a', 'b', 'c'], dtype=object)
>>> for v in sf.values:
... print(v)
...
a
b
c
>>>
预览数据:
>>> list1 = [1,2,3,4,5]
>>> index1 = ['a','b','c','d','e']
>>> sf1 = pd.Series(list1,index=index1)
>>> sf1
a 1
b 2
c 3
d 4
e 5
dtype: int64
>>> sf1['c']
3
>>> sf1.head(2)
a 1
b 2
dtype: int64
>>> sf1.tail(2)
d 4
e 5
dtype: int64
>>>
具有潜在不同类型列的常规二维标记、大小可变的表格结构。
DataFrame是一个类似表格的数据结构,索引包括列索引和行索引,包含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame的每一行和每一列都是一个Series,这个Series的name属性为当前的行索引名/列索引名。
用列表生成DataFrame:
>>> list = [[1,2,3],[4,5,6],[7,8,9]]
>>> df = pd.DataFrame(list,columns=['a','b','c'])
>>> df
a b c
0 1 2 3
1 4 5 6
2 7 8 9
>>> type(df)
<class 'pandas.core.frame.DataFrame'>
>>>
用字典生成DataFrame:
>>> data = {'city':['Beijing', 'Shanghai', 'Tianjin', 'Shenzhen'],
... 'year':[2014, 2015, 2016, 2017],
... 'pop':[2.5, 2.3, 1.1, 0.9]}
>>> df1 = pd.DataFrame(data)
>>> df1
city pop year
0 Beijing 2.5 2014
1 Shanghai 2.3 2015
2 Tianjin 1.1 2016
3 Shenzhen 0.9 2017
>>>
生成一个指定列名的DataFrame:
>>> df2 = pd.DataFrame(data,columns=['city','year','pop','debt'])
>>> df2
city year pop debt
0 Beijing 2014 2.5 NaN
1 Shanghai 2015 2.3 NaN
2 Tianjin 2016 1.1 NaN
3 Shenzhen 2017 0.9 NaN
>>>
获取某列数据(是一个Series结构): DataFrame的单列数据为一个Series。DataFrame是一个带有标签的二维数组,每个标签相当于每一列的列名。
>>> df2['city'] # 以字典方式访问某一个key的值,使用对应的列名,实现单列数据访问
0 Beijing
1 Shanghai
2 Tianjin
3 Shenzhen
Name: city, dtype: object
>>> df2.year # 以属性的方式访问,实现单列数据的访问
0 2014
1 2015
2 2016
3 2017
Name: year, dtype: int64
>>>
根据索引取值、切片:
>>> df2.loc[0] # loc[行索引名称或条件表达式, 列索引名称]。内部传入行索引名称如果为一个区间,则前后均为闭区间。
city Beijing
year 2014
pop 2.5
debt NaN
Name: 0, dtype: object
>>> df2.loc[2]
city Tianjin
year 2016
pop 1.1
debt NaN
Name: 2, dtype: object
>>> df2.iloc[:,0:2] # iloc[行索引位置, 列索引位置]。内部传入的行索引位置或列索引位置为区间时,则为前闭后开区间。
city year
0 Beijing 2014
1 Shanghai 2015
2 Tianjin 2016
3 Shenzhen 2017
>>>
添加列、给列赋值,如果没有值,填充NaN值:
>>> df2['debt'] = 12
>>> df2
city year pop debt
0 Beijing 2014 2.5 12
1 Shanghai 2015 2.3 12
2 Tianjin 2016 1.1 12
3 Shenzhen 2017 0.9 12
>>> df2['y_a_p'] = df2['year']+df2['pop']
>>> df2['abb']=df2['city'].str[:2]
>>> df2['abb1']=df2['city'].str.split('j').str[0]
>>> df2
city year pop debt y_a_p abb abb1
0 Beijing 2014 2.5 12 2016.5 Be Bei
1 Shanghai 2015 2.3 12 2017.3 Sh Shanghai
2 Tianjin 2016 1.1 12 2017.1 Ti Tian
3 Shenzhen 2017 0.9 12 2017.9 Sh Shenzhen
>>> #################################################
>>> def sam_lambda(x):
... if len(x)>=8:
... return x[-3:]
... else:
... return x
...
>>> df2['abb2'] = df2['city'].apply(lambda x: sam_lambda(x))
>>> df2
city year pop debt y_a_p abb abb1 abb2
0 Beijing 2014 2.5 12 2016.5 Be Bei Beijing
1 Shanghai 2015 2.3 12 2017.3 Sh Shanghai hai
2 Tianjin 2016 1.1 12 2017.1 Ti Tian Tianjin
3 Shenzhen 2017 0.9 12 2017.9 Sh Shenzhen hen
>>> #################################################
>>> val = pd.Series([-1.2, -1.5, -1.7], index = [0, 1, 3])
>>> df2['debt'] = val
>>> df2
city year pop debt y_a_p abb abb1 abb2
0 Beijing 2014 2.5 -1.2 2016.5 Be Bei Beijing
1 Shanghai 2015 2.3 -1.5 2017.3 Sh Shanghai hai
2 Tianjin 2016 1.1 NaN 2017.1 Ti Tian Tianjin
3 Shenzhen 2017 0.9 -1.7 2017.9 Sh Shenzhen hen
>>>
删除列:
>>> del df2['abb']
>>> del df2['abb1']
>>> del df2['abb2']
>>> df2
city year pop debt y_a_p
0 Beijing 2014 2.5 -1.2 2016.5
1 Shanghai 2015 2.3 -1.5 2017.3
2 Tianjin 2016 1.1 NaN 2017.1
3 Shenzhen 2017 0.9 -1.7 2017.9
>>>
数据清洗:
>>> df2.loc[4]=pd.Series(['Shenzhen',2017,0.9,-1.7,2017.9],index=df2.columns)
>>> df2
city year pop debt y_a_p
0 Beijing 2014 2.5 -1.2 2016.5
1 Shanghai 2015 2.3 -1.5 2017.3
2 Tianjin 2016 1.1 NaN 2017.1
3 Shenzhen 2017 0.9 -1.7 2017.9
4 Shenzhen 2017 0.9 -1.7 2017.9
>>> df2 = df2.dropna() # 去除空数据
>>> df2
city year pop debt y_a_p
0 Beijing 2014 2.5 -1.2 2016.5
1 Shanghai 2015 2.3 -1.5 2017.3
3 Shenzhen 2017 0.9 -1.7 2017.9
4 Shenzhen 2017 0.9 -1.7 2017.9
>>> >>> df2 = df2.drop_duplicates() # 去除重复数据
>>> df2
city year pop debt y_a_p
0 Beijing 2014 2.5 -1.2 2016.5
1 Shanghai 2015 2.3 -1.5 2017.3
3 Shenzhen 2017 0.9 -1.7 2017.9
>>>
条件选取数据:
>>> df2[df2['year']>=2015]
city year pop debt y_a_p
1 Shanghai 2015 2.3 -1.5 2017.3
3 Shenzhen 2017 0.9 -1.7 2017.9
>>>
分组(group by):
>>> df2.loc[4]=pd.Series(['Shenzhen',2018,1.9,-1.8,2018.9],index=df2.columns)
>>> df2
city year pop debt y_a_p
0 Beijing 2014 2.5 -1.2 2016.5
1 Shanghai 2015 2.3 -1.5 2017.3
3 Shenzhen 2017 0.9 -1.7 2017.9
4 Shenzhen 2018 1.9 -1.8 2018.9
>>> df2.groupby(by=['city']).mean()
year pop debt y_a_p
city
Beijing 2014.0 2.5 -1.20 2016.5
Shanghai 2015.0 2.3 -1.50 2017.3
Shenzhen 2017.5 1.4 -1.75 2018.4
>>>
在Pandas中DataFrame数据整合,需要使用链接操作。
行链接:
concat方法相当于数据库中的全链接(union all),它不仅可以指定链接的方式(outer join或inner join),还可以指定按照某个轴进行链接。与数据库不同的是,它不会去重,但是可以使用drop_duplicates方法达到去重的效果。参数axis默认是0,指定为行。
>>> df1
city pop year
0 Beijing 2.5 2014
1 Shanghai 2.3 2015
2 Tianjin 1.1 2016
3 Shenzhen 0.9 2017
>>> df2
city year pop debt y_a_p
0 Beijing 2014 2.5 -1.2 2016.5
1 Shanghai 2015 2.3 -1.5 2017.3
3 Shenzhen 2017 0.9 -1.7 2017.9
4 Shenzhen 2018 1.9 -1.8 2018.9
>>> df3 = pd.concat([df1,df2]) # 行链接--concat
>>> df3
city debt pop y_a_p year
0 Beijing NaN 2.5 NaN 2014
1 Shanghai NaN 2.3 NaN 2015
2 Tianjin NaN 1.1 NaN 2016
3 Shenzhen NaN 0.9 NaN 2017
0 Beijing -1.2 2.5 2016.5 2014
1 Shanghai -1.5 2.3 2017.3 2015
3 Shenzhen -1.7 0.9 2017.9 2017
4 Shenzhen -1.8 1.9 2018.9 2018
>>>
列链接:
使用数据库样式的链接合并DataFrame或命名的Series对象。
链接在列或索引上完成。 如果在列上链接列,则DataFrame索引将被忽略。 否则,如果在索引上链接索引或在一个或多个列上建立索引,则将传递索引。
>>> data = {'city':['Beijing', 'Shanghai', 'Tianjin', 'Shenzhen'],
... 'area':[320, 350, 240, 220],
... 'post':['10', '20', '11', '22']}
>>> df4 = pd.DataFrame(data)
>>> df4
area city post
0 320 Beijing 10
1 350 Shanghai 20
2 240 Tianjin 11
3 220 Shenzhen 22
>>> df1
city pop year
0 Beijing 2.5 2014
1 Shanghai 2.3 2015
2 Tianjin 1.1 2016
3 Shenzhen 0.9 2017
>>> df5 = pd.merge(df1,df4,on='city') # 列链接--merge
>>> df5
city pop year area post
0 Beijing 2.5 2014 320 10
1 Shanghai 2.3 2015 350 20
2 Tianjin 1.1 2016 240 11
3 Shenzhen 0.9 2017 220 22
>>>
索引合并:
在索引或键列上将列与其他DataFrame链接起来。 通过传递一个列表,一次有效地通过索引链接多个DataFrame对象。
>>> df1
city pop year
0 Beijing 2.5 2014
1 Shanghai 2.3 2015
2 Tianjin 1.1 2016
3 Shenzhen 0.9 2017
>>> df2
city year pop debt y_a_p
0 Beijing 2014 2.5 -1.2 2016.5
1 Shanghai 2015 2.3 -1.5 2017.3
3 Shenzhen 2017 0.9 -1.7 2017.9
4 Shenzhen 2018 1.9 -1.8 2018.9
>>> df1.join(df2, lsuffix='_caller', rsuffix='_other')
city_caller pop_caller year_caller city_other year_other pop_other debt y_a_p
0 Beijing 2.5 2014 Beijing 2014.0 2.5 -1.2 2016.5
1 Shanghai 2.3 2015 Shanghai 2015.0 2.3 -1.5 2017.3
2 Tianjin 1.1 2016 NaN NaN NaN NaN NaN
3 Shenzhen 0.9 2017 Shenzhen 2017.0 0.9 -1.7 2017.9
>>>
CSV数据:
将逗号分隔值(csv)文件读取到DataFrame中。
./abc.csv 文件内容:
a,b,c,d,message
1,2,3,4,zhangsan
5,6,7,8,lisi
9,10,11,12,wangmazi
>>> import pandas as pd
>>> df = pd.read_csv('abc.csv') # 打开后默认添加索引(index)为从0自增长,列(columns)默认采用第一行数据
>>> df
a b c d message
0 1 2 3 4 zhangsan
1 5 6 7 8 lisi
2 9 10 11 12 wangmazi
>>> df1 = pd.read_csv('abc.csv', header=None) # header参数指定列(columns)采用为从0自增长的数
>>> df1
0 1 2 3 4
0 a b c d message
1 1 2 3 4 zhangsan
2 5 6 7 8 lisi
3 9 10 11 12 wangmazi
>>> df2 = pd.read_csv('abc.csv', names=['first','second','third','fourth']) # 用names参数指定列(columns)的值
>>> df2
first second third fourth
a b c d message
1 2 3 4 zhangsan
5 6 7 8 lisi
9 10 11 12 wangmazi
>>> df3 = pd.read_csv('abc.csv', index_col='message') # 用index_col参数指定的列的首元素,使得该列作为索引index
>>> df3
a b c d
message
zhangsan 1 2 3 4
lisi 5 6 7 8
wangmazi 9 10 11 12
>>>
将对象写入逗号分隔值(csv)文件。
>>> df.head(2).to_csv('abc.csv') # 其中head(2)表示将前两行写入文件
>>> ''' 写入的文件内容:
... ,a,b,c,d,message
... 0,1,2,3,4,zhangsan
... 1,5,6,7,8,lisi
... '''
>>> df = pd.read_csv('abc.csv')
>>> df
Unnamed: 0 a b c d message
0 0 1 2 3 4 zhangsan
1 1 5 6 7 8 lisi
>>> df1.head(2).to_csv('abc.csv',index=False,header=False) # 参数index与header默认为True,在此表示把索引(index)和列头(columns)都弃掉
>>> ''' 写入文件的内容:
... a,b,c,d,message
... 1,2,3,4,zhangsan
... '''
>>> df1 = pd.read_csv('abc.csv')
>>> df1
a b c d message
0 1 2 3 4 zhangsan
>>>
Pandas实现的绘图功能基于matplotlib的API,Matplotlib是一个Python的 二维(2D)绘图库,其可以在各种平台及交互式环境生成具有出版品质的图形。在使用Pandas绘图之前,需要安装matplotlib库包:
pip install matplotlib
matplotlib的pyplot模块提供了绘图界面,先将其导入:
import matplotlib.pyplot as plt
使用pyplot模块的plot函数来绘图: 先导入模块pyplot,然后使用该模块的plot函数绘制折线图,接着调用该模块的相关函数来调整、设置图表的标题、横纵标签、刻度标记内容或大小。
>>> import matplotlib.pyplot as plt
>>> plt.rcParams['font.sans-serif'] = 'SimHei' # 设置使得中文正常显示
>>> squares = [1, 4, 9, 16, 25]
>>> plt.plot(squares, linewidth=5) # 指定一个列表当作是Y参数,列表的索引值为X参数从0开始。设置线宽为5
[<matplotlib.lines.Line2D object at 0x11e313550>]
>>> plt.title(u'平方数', fontsize=24) # 指定标题,并设置标题字体大小
Text(0.5,1,'平方数')
>>> plt.xlabel(u'值', fontsize=14) # 指定X坐标轴的标签,并设置标签字体大小
Text(0.5,0,'值')
>>> plt.ylabel(u'平方值', fontsize=14) # 指定Y坐标轴的标签,并设置标签字体大小
Text(0,0.5,'平方值')
>>> plt.tick_params(axis='both', labelsize=14) # 参数axis值为both,代表要设置横纵的刻度标记,标记大小为14
>>> plt.show() # 打开matplotlib查看器,并显示绘制的图形
在Pandas中,pandas.Series.plot(self, *args, **kwargs)
和pandas.DataFrame.plot(self, *args, **kwargs)
上面使用plot方法进行绘图,只是围绕着matplotlib.pyplot.plot(*args, **kwargs)
方法的简单封装。
>>> import matplotlib.pyplot as plt
>>> import pandas as pd
>>> list1 = [1,2,3,4,5]
>>> index1 = ['a','b','c','d','e']
>>> sf1 = pd.Series(list1,index=index1)
>>> sf1.plot(kind='line')
<matplotlib.axes._subplots.AxesSubplot object at 0x112e74f98>
>>> sf1.plot(kind='bar')
<matplotlib.axes._subplots.AxesSubplot object at 0x112e74f98>
>>> plt.show()
博文最后更新时间: