一、pandas环境的搭建
1.pandas 简介
Python Data Analysis Library
pandas是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型结构化数据集所需的工具。
pandas提供了大量能使我们快速便捷地处理数据的函数和方法。Python长期以来一直非常适合数据整理和准备,你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之 一。
pandas是python里面分析结构化数据的工具集,基础是numpy,图像库是matplotlib。
2.pandas安装和调用
pandas官网 :https://pandas.pydata.org/
安装:pip install pandas
调用:import pandas as pd
二、pandas学习
1.pandas简介
Python Data Analysis Library
pandas是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型结构化数据集所需的工具。
pandas提供了大量能使我们快速便捷地处理数据的函数和方法。Python长期以来一直非常适合数据整理和准备,你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之 一。
pandas是python里面分析结构化数据的工具集,基础是numpy,图像库是matplotlib。
2.pandas学习资源
pandas官网 :https://pandas.pydata.org/
3.pandas核心数据结构
数据结构是计算机存储、组织数据的方式。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
4.Series
a.Series定义
Series可以理解为一个一维的数组,只是index名称可以自己改动。类似于定长的有序字典,有Index和 value。index赋值必须是list类型。
Series官方文档:https://pandas.pydata.org/docs/reference/series.html
# 创建函数 Series([data, index, dtype, name, copy, …])
参数名称 | 说明 |
data | 数据源 |
index | 索引,赋值必须为列表 |
dtype | 元素数据类型 |
name | Series的名称 |
b.Series的创建
import pandas as pd import numpy as np # 创建一个空的系列 s = pd.Series() # 从ndarray创建一个Series data = np.array(['张三','李四','王五','赵柳']) s = pd.Series(data) # 增加index,index赋值必须是列表类型 s = pd.Series(data,index=['100','101','102','103'], name='series_name') # 从字典创建一个Series,字典的键作为series的键,字典的值作为series的数据 data = {'S100': '张三', 'S101': '李四', 'S102': '王五', 'S103': '赵六', 'S104': '杨七'} s = pd.Series(data) # 从标量创建一个Series s = pd.Series(5, index=[0, 1, 2, 3]) s
c.Series中数据的访问
# 1.使用索引检索元素 s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e']) print(s) print(s[0]) print(s[[0,1,2]]) print(s[s>3]) print(s[:3]) print(s[-3:]) # 2.使用(index)标签检索数据 print(s['a']) print(s[['a','c','d']]) print(s['a':'d'])
d.Series的常用属性
属性名称 | 说明 |
Series.index | 系列的索引(轴标签) |
Series.array | 支持该系列或索引的数据的ExtensionArray |
Series.values | Series的值。根据dtype将Series返回为ndarray或类似ndarray |
Series.dtype | 返回基础数据的dtype对象 |
Series.shape | 返回基础数据形状的元组 |
Series.nbytes | 返回基础数据中的字节数 |
Series.ndim | 返回基础数据的维数(轴数) |
Series.size | 返回基础数据中的元素数 |
Series.T | 返回转置 |
Series.dtypes | 返回基础数据的dtype对象 |
Series.memory_usage([index,deep]) | 返回该系列的内存使用情况 |
Series.hasnans | 如果有nans,就返回True |
Series.empty | 指示DataFrame是否为空,如果为空则返回True |
Series.name | 返回系列的名称 |
示例:
# 创建一个series s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e'], name='series_name') # 显示series print(s) print(s.index) print(s.array) print(s.values) print(s.dtype) print(s.shape) print(s.nbytes) print(s.ndim) print(s.size) print(s.T) print(s.dtypes) print(s.memory_usage()) print(s.hasnans) print(s.empty) print(s.name)
pandas日期类型数据处理
# pandas识别的日期字符串格式 dates = pd.Series(['2011', '2011-02', '2011-03-01', '2011/04/01', '2011/05/01 01:01:01', '01 Jun 2011']) # to_datetime() 转换日期数据类型 dates = pd.to_datetime(dates) print(dates, dates.dtype) print(type(dates)) 0 2011-01-01 00:00:00 1 2011-02-01 00:00:00 2 2011-03-01 00:00:00 3 2011-04-01 00:00:00 4 2011-05-01 01:01:01 5 2011-06-01 00:00:00 dtype: datetime64[ns] datetime64[ns] <class 'pandas.core.series.Series'> # 获取时间的某个日历字段的数值 print(dates.dt.day) 0 1 1 1 2 1 3 1 4 1 5 1 dtype: int64
Series.dt提供了很多日期相关操作,如下:
Series.dt.year The year of the datetime. Series.dt.month The month as January=1, December=12. Series.dt.day The days of the datetime. Series.dt.hour The hours of the datetime. Series.dt.minute The minutes of the datetime. Series.dt.second The seconds of the datetime. Series.dt.microsecond The microseconds of the datetime. Series.dt.week The week ordinal of the year. Series.dt.weekofyear The week ordinal of the year. Series.dt.dayofweek The day of the week with Monday=0, Sunday=6. Series.dt.weekday The day of the week with Monday=0, Sunday=6. Series.dt.dayofyear The ordinal day of the year. Series.dt.quarter The quarter of the date. Series.dt.is_month_start Indicates whether the date is the first day of the month. Series.dt.is_month_end Indicates whether the date is the last day of the month. Series.dt.is_quarter_start Indicator for whether the date is the first day of a quarter. Series.dt.is_quarter_end Indicator for whether the date is the last day of a quarter. Series.dt.is_year_start Indicate whether the date is the first day of a year. Series.dt.is_year_end Indicate whether the date is the last day of the year. Series.dt.is_leap_year Boolean indicator if the date belongs to a leap year. Series.dt.days_in_month The number of days in the month.
日期运算:
# datetime日期运算 delta = dates - pd.to_datetime('1970-01-01') print(delta, delta.dtype, type(delta)) 0 14975 days 00:00:00 1 15006 days 00:00:00 2 15034 days 00:00:00 3 15065 days 00:00:00 4 15095 days 01:01:01 5 15126 days 00:00:00 dtype: timedelta64[ns] timedelta64[ns] <class 'pandas.core.series.Series'> # 把时间偏移量换算成天数 print(delta.dt.days) 0 14975 1 15006 2 15034 3 15065 4 15095 5 15126 dtype: int64
通过指定周期和频率,使用date_range()函数就可以创建日期序列。 默认情况下,频率是’D’。
import pandas as pd # 以日为频率 datelist = pd.date_range('2019/08/21', periods=5) print(datelist) DatetimeIndex(['2019-08-21', '2019-08-22', '2019-08-23', '2019-08-24', '2019-08-25'], dtype='datetime64[ns]', freq='D') # 以月为频率 datelist = pd.date_range('2019/08/21', periods=5,freq='M') print(datelist) DatetimeIndex(['2019-08-31', '2019-09-30', '2019-10-31', '2019-11-30', '2019-12-31'], dtype='datetime64[ns]', freq='M') # 构建某个区间的时间序列 start = pd.datetime(2017, 11, 1) end = pd.datetime(2017, 11, 5) dates = pd.date_range(start, end) print(dates) DatetimeIndex(['2017-11-01', '2017-11-02', '2017-11-03', '2017-11-04', '2017-11-05'], dtype='datetime64[ns]', freq='D')
bdate_range()用来表示商业日期范围,不同于date_range(),它不包括星期六和星期天。
import pandas as pd datelist = pd.bdate_range('2011/11/03', periods=5) print(datelist) DatetimeIndex(['2011-11-03', '2011-11-04', '2011-11-07', '2011-11-08', '2011-11-09'], dtype='datetime64[ns]', freq='B')
5.DataFrame
a.DataFrame定义
DataFrame是一个类似于表格的数据类型,可以理解为一个二维数组,索引有两个维度,可更改。DataFrame具有以下特点:
列可以是不同的类型
大小可变
标记轴(行和列)
针对行与列进行轴向统计
b.DataFrame创建
DataFrame统一的创建形式为:
import pandas as pd pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)
参数名称 | 说明 |
data | 数据ndarray(结构化或同类),Iterable,dict或DataFrame |
index | 行标签,或类似数组 |
columns | 列标签,或类似数组 |
dtype | 元素数据类型 |
copy | 是否可复制 |
示例:
import pandas as pd # 1.创建一个空的DataFrame df = pd.DataFrame() print(df) # 2.从列表创建DataFrame data = [1,2,3,4,5] df = pd.DataFrame(data) print(df) # 3.从二维列表创建DataFrame data = [['Alex',10],['Bob',12],['Clarke',13]] df = pd.DataFrame(data,columns=['Name','Age'],dtype=float) print(df) # 4.从列表嵌套字典创建DataFrame data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}] df = pd.DataFrame(data) print(df) # 5.从字典创建DataFrame data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]} df = pd.DataFrame(data, index=['s1','s2','s3','s4']) print(df) # 6.从字典创建DataFrame data = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(data) print(df)
c.DataFrame常用属性
属性名称 | 描述 |
DataFrame.index | DataFrame的索引(行标签) |
DataFrame.columns | DataFrame的列标签 |
DataFrame.dtypes | 返回DataFrame中元素的dtype |
DataFrame.info | 打印DataFrame的简要摘要 |
DataFrame.select_dtypes | 根据列dtypes返回DataFrame列的子集 |
DataFrame.values | 返回DataFrame的值,返回值为ndarry |
DataFrame.axes | 返回一个表示DataFrame轴的列表 |
DataFrame.ndim | 返回一个表示轴数/数组维数的整数 |
DataFrame.size | 返回表示此对象中元素数量的整数 |
DataFrame.shape | 返回一个表示DataFrame维数(形状)的元组 |
DataFrame.memory_usage([index,deep]) | 返回每列的内存使用情况(以字节为单位) |
DataFrame.empty | 指示DataFrame是否为空 |
示例:
import pandas as pd # 创建DataFrame data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]} df = pd.DataFrame(data, index=['s1','s2','s3','s4']) print(df) # 添加score列 df['score']=pd.Series([90, 80, 70, 60], index=['s1','s2','s3','s4']) print(df) # 轴的列表 print(df.axes) # 数据类型 print(df['Age'].dtype) # 是否空DataFrame print(df.empty) # 轴数 print(df.ndim) # 元素个数 print(df.size) 12 # 行标签 print(df.index) # 值 print(df.values) # df的前三行 print(df.head(3)) # df的后三行 print(df.tail(3))
d.核心数据结构操作
显示索引,列
import pandas as pd # 创建DataFrame data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]} df = pd.DataFrame(data, index=['s1','s2','s3','s4']) df.index df.columns
索引选择
操作 | 语法 | 返回值 |
选择列 | df[col] | Series |
按标签选择行 | df.loc[label] | Series |
按整数位置选择行 | df.iloc[loc] | Series |
切片行 | df[5:10] | DataFrame |
通过布尔向量选择行 | df[bool_vec] | DataFrame |
复合索引
DataFrame的行级索引与列级索引都可以设置为复合索引,表示从不同的角度记录数据。
data = np.floor(np.random.normal(85, 3, (6,3))) df = pd.DataFrame(data) index = [('classA', 'F'), ('classA', 'M'), ('classB', 'F'), ('classB', 'M'), ('classC', 'F'), ('classC', 'M')] df.index = pd.MultiIndex.from_tuples(index) columns = [('Age', '20+'), ('Age', '30+'), ('Age', '40+')] df.columns = pd.MultiIndex.from_tuples(columns)
复合索引的访问:
# 访问行 df.loc['classA'] df.loc['classA', 'F'] df.loc[['classA', 'classC']] # 访问列 df.Age df.Age['20+'] df['Age'] df['Age', '20+']
列操作
列访问
DataFrame的单列数据为一个Series。根据DataFrame的定义可以知晓DataFrame是一个带有标签的二维数组,每个标签相当每一列的列名。
d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']), 'three' : pd.Series([1, 3, 4], index=['a', 'c', 'd'])} df = pd.DataFrame(d) print(df) # 列访问 df[df.columns[:2]] df[['one','two']] df[df.columns[[0,2]]]
列添加
DataFrame添加一列的方法非常简单,只需要新建一个列索引。并对该索引下的数据进行赋值操作即可。
import pandas as pd # 新建一个列索引,并赋值 # 当插入与DataFrame索引不同的Series时,它将符合DataFrame的索引 # 可以插入原始ndarray,但它们的长度必须与DataFrame索引的长度匹配,默认情况下,列会插入到末尾。 df['four']=pd.Series([90, 80, 70, 60], index=['a', 'b', 'c', 'd']) print(df) # insert功能可插入到列中的特定位置 df.insert(1, 'five', df['one'])
列删除
删除某列数据需要用到pandas提供的方法del、pop、drop方法,用法如下:
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']), 'three' : pd.Series([10, 20, 30], index=['a', 'b', 'c']), 'four' : pd.Series([40, 50, 60], index=['a', 'b', 'c']), 'five' : pd.Series([70, 80, 90], index=['a', 'b', 'c'])} df = pd.DataFrame(d) df # del方法删除 del(df['one']) print(df) # pop方法删除 df.pop('two') print(df) # drop方法删除 df.drop(['three'], axis=1)
drop
删除某列或某行数据 ,drop方法的用法如下。 axis为0时表示删除行,axis为1时表示删除列。
drop(labels, axis=0, level=None, inplace=False, errors='raise')。
常用参数:
参数名称 | 说明 |
labels | 接受string或array。代表删除的行或列的标签,无默认。 |
axis | 接受0或1。代表标签所在轴。默认为None。 |
levels | 接收int或者索引名。代表标签所在级别。默认为None。 |
inplace | 接收boolean。代表操作是否对原数据生效。默认为False。 |
行操作
行访问
如果只是需要访问DataFrame某几行数据的实现方式则采用数组的选取方式,使用 “:” 即可:
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print(df[2:4]) print(df['a':'c’])
loc是针对DataFrame索引名称的切片方法。如果传入的不是索引名称,那么切片操作将无法执行,利用loc方法,能够实现所有单层索引切片操作。
loc方法使用方法如下:DataFrame.loc[行索引名称或条件, 列索引名称]
select by label : loc
标签参数查找DataFrame.loc[index:index,[‘columns’]],loc方法当中的columns可以选择多列,如果表示只按列选择的话index可以不填但是冒号(:)和逗号 (,)一定要写。
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print(df.loc['b']) print(df.loc[['a', 'b']]) print(df.loc['a':'c']) print(df.loc['a':'c','one':'two'])
iloc和loc区别是iloc接收的必须是行索引和列索引的位置。iloc方法的使用方法如下:
DataFrame.iloc[行索引位置, 列索引位置]。
select by position:iloc
索引查找,把标签换成绝对位置。
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print(df.iloc[2]) print(df.iloc[[2, 3]]) print(df.iloc[2:3,0:1])
行添加
import pandas as pd df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age'], index=[0, 1]) df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['Name','Age'], index=[2, 3]) df = df.append(df2) print(df) DataFrame.append(other, ignore_index=False, verify_integrity=False, sort=False)
参数 | 说明 |
other | DataFrame或类似Series / dict的对象,要追加的数据 |
ignore_index | 如果为True,则结果轴将标记为0、1,…,n-1 |
verify_integrity | 如果为True,则在创建具有重复项的索引时引发ValueError |
sort | 布尔值,默认为False |
返回:DataFrame
行删除
使用索引标签从DataFrame中删除列或删除行。 如果标签重复,则会删除多行。
import pandas as pd df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age']) df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['Name','Age']) df = df.append(df2) # 删除index为0的行 df = df.drop(0) print(df)
修改DataFrame中的数据
更改DataFrame中的数据,原理是将这部分数据提取出来,重新赋值为新的数据。
import pandas as pd df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age']) df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['Name','Age']) df = df.append(df2) df['Name'][0] = 'Tom' print(df)
数据对齐
DataFrame对象之间的数据会自动**在列和索引(行标签)**上对齐。同样,结果对象将具有列标签和行标签的并集。对于缺失值将自动补全NaN。
df = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D']) df2 = pd.DataFrame(np.random.randn(7, 3), columns=['A', 'B', 'C']) df + df2
DataFrame的运算
add() sub() mul() div() # 二进制运算 radd() rsub() rmul() rdiv()
在DataFrame和Series之间进行操作时,默认行为是在DataFrame列上对齐Series索引,从而 逐行广播。
df = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D']) df # 每一行都要进行计算 df - df.iloc[0]
在处理时间序列数据的特殊情况下,如果DataFrame索引包含日期,则广播将按列进行
index = pd.date_range('1/1/2000', periods=8) df = pd.DataFrame(np.random.randn(8, 3), index=index, columns=list('ABC')) df type(df['A']) df - df['A'] # 现在已弃用,并将在以后的版本中删除 df.sub(df['A'], axis=0)
DataFrame与数字的运算
df * 5 + 2 1 / df df ** 4
DataFrame的布尔运算符
df1 = pd.DataFrame({'a': [1, 0, 1], 'b': [0, 1, 1]}, dtype=bool) df2 = pd.DataFrame({'a': [0, 1, 1], 'b': [1, 1, 0]}, dtype=bool) df1 & df2 df1 | df2 df1 ^ df2 ~df1
DataFrame的转置
要进行转置,请访问T属性(也可以用transpose函数),类似于ndarray
df = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D']) df.T df.transpose()
e.apply函数
Series.apply(func,convert_dtype = True,args = (),** kwds) DataFrame.apply(func,axis = 0,raw = False,result_type = None,args = (),** kwds)
参数说明:
参数名称 | 说明 |
func | 需要执行的函数名称 |
convert_dtype | 尝试找到更好的dtype以获得逐元素函数结果。如果为False,则保留为dtype = object。 |
args | 在series值之后将位置参数传递给func |
**kwds | 传递给func的其他关键字参数 |
axis | {0或’index’,1或’columns’},默认0 |
raw | 确定是否将行或列作为Series或ndarray对象传递,bool默认为False |
result_type | {‘expand’,‘reduce’,‘broadcast’,None},默认为None,仅在axis=1(列)时起作用 |
pandas提供了apply函数方便的处理Series与DataFrame;apply函数支持逐一处理数据集中的每个元素都会执行一次目标函数,把返回值存入结果集中。
# series.apply() ary = np.array(['80公斤','83公斤','78公斤','74公斤','84公斤']) s = pd.Series(ary) def func(x): return x[:2] s.apply(func) # dataframe.apply() def func(x): x[pd.isna(x)] = x.mean() return x ratings.apply(func, axis=1)