3 Pandas

Pandas介绍与安装

为什么会有Pandas?

Pandas支持大部分Numpy语言风格,尤其是数组函数与广播机制的各种数据处理。但是Numpy更适合处理同质型的数据。而Pandas的设计就是用来处理表格型或异质型数据的,高效的清洗、处理数据。

Pandas是什么?

Pandas是基于Numpy的一种工具,提供了高性能矩阵的运算,该工具是为了解决数据分析任务而创建的。也是贯穿整个Python数据分析非常核心的工具。

Pandas涉及内容

在这里插入图片描述

Pandas安装

直接在dos命令行中pip install pandas 即可。

Pandas基础数据结构

series

Series介绍

Series是一种一维的数组型对象,它包含了一个值序列(values),并且包含了数据标签,称为索引(index)。

Series创建

pd.Series(data=None,index=None,dtype=None,name=None,copy=False)

  • data:创建数组的数据,可为array-- --like, dict, or scalar value
  • index:指定索引
  • dtype:数组数据类型
  • name:数组名称
  • copy:是否拷贝

data可为iterable, dict, or scalar value

import pandas as pd
pd.Series([1,2,3,4,5,6])	# data为iterable

索引默认为range(0,n) 可以通过index指定索引

pd.Series([1,2,3,4,5]),index=list("abcde"))

数据类型根据data自动调整,但是也可以通过dtype指定

pd.Series(np.random.randint(1,10,size=5),dtype="float")

使用name参数设置数组名称

pd.Series(np.random.randint(1,10,size=3),index=list("abc"),name="data_name")

除此之外,Pandas可以使用Numpy的数组函数。

  • s.dtype # 查看数据类型
  • s.astype() # 修改数据类型
  • s.head(n) # 预览数据前5条
  • s.tail(n) # 预览数据后五条
    但是如果需要显示所有数据,则需以下代码。但并不建议使用
# 显示所有列
pd.set_option('display.max_columns',None)

# 显示所有行
pd.set_option('display.max_rows',None)

#设置value的显示长度为100,默认50
pd.set_option('max_colwidth',100)

series的索引与值

  • s.index # 查看索引
  • s.values # 查看值的序列
  • s.reset_index(drop=False) # 重置索引
    • drop # 是否删除原索引 默认为否

注意

  • 索引对象是不可变的,所以不能单个修改索引

Series索引与切片

  • s[‘标签’] # 通过标签
  • s[‘索引’] # 通过索引
  • s.loc(标签) # 通过标签
  • s.iloc(索引) # 通过索引

Series运算

  • 共同索引对应为运算,其他填充NaN
S1 = pd.Series(range(10,20),index=range(10))

s2 = pd.Series(range(20,25),index=range(5))

s1+s2
  • 没有共同索引时,则全部为NaN

DataFrame

DataFrame介绍

DataFrame介绍表示的是矩阵的数据表,它包含已排序的列集合,每一列可以是不同的值类型(数值,字符串,布尔值)。在DataFrame中,数据被存储为一个以上的二维块。
在这里插入图片描述

DataFrame创建

pd.DataFrame(data=None,index=None,columns=None,dtype=None,copy=False)

  • data:创建数组的数据,可为ndarray,dict
  • index:创建索引
  • dtype:数组数据类型
  • copy:是否拷贝

重置索引

除了创建时可以指定,我们创建后还可以通过df.reindex()进行重置索引。

  • df.reindex(index=None,columns=None,axis=None,fill_value=NaN)

DataFrame基础操作

  • df.shape # 查看数组情况,返回值为元祖
  • df.dtypes # 查看列数据类型
  • df.ndim # 数据维度,返回为整数
  • df.index # 行索引
  • df.columns # 列索引
  • df.values # 值
  • df.head(n) # 显示头部几行,默认前5行
  • df.tail(n) # 显示末尾几行,默认后5行
  • df.info() # 相关信息概述
data = [
    {"name":"amy","age":18,"tel":10086},
    {"name":"bob","age":18},
    {"name":"james","tel":10086},
    {"name":"zs","tel":10086},
    {"name":"james","tel":10086},
    {"name":"ls","tel":10086},
]

d2 = pd.DataFrame(data)
d2.head()  
d2.tail()  
d2.info()  

DataFrame查数据(索引与切片)

直接使用索引与标签:

类型描述
df[:索引]或df[:“标签”]表示对行操作
df[“列标签”]或df[[“列标签”,“列标签”]]表示对列进行操作
练习1
读取文件catNames2.csv
  • 取前两行
  • 取出Count_AnimalName列
  • 取出Row_Labels前两行
    练习2
    找到所有的使用次数超过800的猫的名字
    使用loc及iloc查询数据:
  • df.loc[] 通过轴标签选择数据
  • df.iloc[] 通过整数索引选择数据
    具体使用如下
类型描述
df.loc[val]根据标签索引选择DataFrame的单行或多行
df.loc[:,val]根据标签索引选择DataFrame的单列或多列
df.loc[val1,val2]同时选择行和列中的一部分
df.iloc[where]根据位置索引选择DataFrame的单行或多行
df.iloc[:,where]根据位置索引选择DataFrame的单列或多列
df.iloc[where_i,where_j]根据位置索引选择行和列
注意:
df[val1:val2] 不加loc或iloc时 val1代表列;val2代表行,反之则val1代表行;val2代表列。
例如:df[[1,2]:[1,2]]

DataFrame修改数据

修改数据主要遵循以下两点:

  • 查询数据
  • 再赋值

注意
Pandas中可以直赋值np.NaN,且赋值当前列数据会自动转为浮点类型。而不是整个数组都转,这主要是因为Pandas数据可以是异质性。

DataFrame新增数据

新增列: df[“新的列标签”] = 值
注意:添加列,则新添加的值的长度必须与其它列的长度保持一致,否则会报错。
插入列: 如果需要在数据中心插入列,则使用 df.insert(loc,column,value)

  • loc 为插入列的位置
  • columns 为插入列的标签
  • value 为插入列的值
    添加行: df.loc[“新的行标签”,:] = 值
    除此之外,我们还可以通过df.append(df2)方法添加行,但类似于数组与数组的堆叠拼接。所以df2的列索引必须同df一致。

DataFrame删除数据

方法1:del df[“列标签”]
方法2:df.drop(axis =0,index =None,columns =None,inplace =False)

DataFrame算术

实际上,通过+ - * / // **等符号可以直接对DataFrame与DataFrame之间或者DataFrame以及Series之间进行运算。但秉承的原则是对应索引运算,存在索引不同时,返回结果为索引对的并集
使用填充值的算术方法

方法描述
add,radd加法(+)
sub,rsub减法(-)
div,rdiv除法(/)
floordiv,rfloordiv整除(//)
mul,rmul乘法(*)
pow,rpow幂次方(**)

注意

  • Series使用算术方法,不支持指定填充值
    描述性统计的概述和计算
方法描述
count非NA值的个数
min,max最小值,最大值
idxmin,idxmax最小值,最大值的标签索引
sum求和
mean平均值
median中位数
var方差
std标准差
cumsum累计值
cummin,cummax累计值的最小值或最大值
cumprod值的累计积
diff计算第一个算术差值(时间序列)
pct_change百分比
corr按索引对其的值的相关性
cov协方差
DataFrame排序
  • df.sort_index(axis=0,ascending=True) # 索引排序
    • axis指定轴,默认为0轴
    • ascending为排序方式,默认为True表示升序
  • df.sort_values(by) # 值排序
    • by指定一列或多列作为排序键
      注意
  • by = [col1,col2] 是先给col1排序,当col11有相同值时,col2中安排续顺序再排序
    练习
    关于猫的名字的统计数据,获取用次数最高的名字
    函数应用于映射
  • df.apply(func,axis=0) # 通过apply将函数运用到列或者行
  • df.applymap(func) # applymap将函数应用到每个数据上

数据读取存储

在这里插入图片描述
在这里插入图片描述

csv文件

  1. 读取csv文件read_csv(file_path or buf,usecols,encoding)
    file_path:文件路径
    usecols:指定读取的列名
    encoding:编码
data = pd.read_csv('d:/test_data/food_rank.csv',encoding='utf8')
data.head()
    name    num
0    酥油茶    219.0
1    青稞酒    95.0
2    酸奶    62.0
3    糌粑    16.0
4    琵琶肉    2.0

#指定读取的列名
data = pd.read_csv('d:/test_data/food_rank.csv',usecols=['name'])
data.head()
    name
0    酥油茶
1    青稞酒
2    酸奶
3    糌粑
4    琵琶肉

#如果文件路径有中文,则需要知道参数engine='python'
data = pd.read_csv('d:/数据/food_rank.csv',engine='python',encoding='utf8')
data.head()
    name    num
0    酥油茶    219.0
1    青稞酒    95.0
2    酸奶    62.0
3    糌粑    16.0
4    琵琶肉    2.0
#建议文件路径和文件名,不要出现中文
  1. 写入csv文件
    DataFrameto_csv(file_path or buf,sep,columns,header,index,na_rep,mode)
    file_path:保存文件路径,默认None
    sep:分隔符,默认’,’
    columns:是否保留某列数据,默认None
    header:是否保留列名,默认True
    index:是否保留行索引,默认True
    np_rep:指定字符串来代替空值,默认是空字符
    mode:默认‘w’,追加‘a’
   **Series**:`Series.to_csv`\(_path=None_,_index=True_,_sep='_,_'_,_na\_rep=''_,_header=False_,_mode='w'_,_encoding=None_\)

数据库交互

  • pandas
  • sqlalchemy
  • pymysql
# 导入必要模块
import pandas as pd
from sqlalchemy import create_engine

# 初始化数据库连接
# 用户名root 密码 3306 数据库db2
engine = creat_engine('mysql+pymysql://root:@localhost:3306/db2')
# 查询语句
sql = '''
		select * from class;
		'''
# 两个参数    sql语句  数据库连接
df = pd.read_sql(sql,engine)
df

在这里插入图片描述

# 新建
df = pd.DataFrame({'id':[1,2,3,4],'num':[34,56,78,90]})
df = pd.read_csv('ex1.csv')
# 写入到数据库
df.to_sql('df2',engine,index=False)
print("ok")

进数据库查看:
在这里插入图片描述

Pandas数据清洗

数据清洗介绍

数据清洗实际上也是数据质量分析,检查原始数据中是否存在脏数据(不符合要求,或者不能直接进行分析的数据),并且处理脏数据。
常见情况如下

  • 缺失值
  • 异常值
  • 重复数据

处理缺失值

Pandas使用浮点值NaN(Not a Number)表示缺失值,并且缺失值在数据中时常出现。那么Pandas的目的之一就是**“无痛的”**处理缺失值。
判断数据是否为NaN

  • pd.isnull(df) 返回哪些值是缺失值的布尔值
  • pd.notnull(df) 返回值时isnull的反集
    注意
  • Python内建的None值也被当做NaN
    过滤缺失值
  • dropna(axis=0,how=‘any’,inplace=False)
    • axis 指定轴 默认为0 代表行
    • how 默认为any 代表删除含有NaN的行 当为all时代表删除所有值为NaN的行
    • inplace 修改被调用的对象 而不是一个备份(不用再赋值了,直接使用)
      • inplace=False,默认该删除操作不改变原数据,而是返回一个执行删除操作后的新dataframe;
      • inplace=True,则会直接在原数据上进行删除操作,删除后无法返回。

pandas—删除某行或某列数据

# 创建一个DataFrame格式数据
data = {'a': ['a0', 'a1', 'a2'],
        'b': ['b0', 'b1', 'b2'],
        'c': [i for i in range(3)],
        'd': 4}
df = pd.DataFrame(data)
print('举例数据情况:\n', df)

在这里插入图片描述
注:DataFrame是最常用的pandas对象,使用pandas读取数据文件后,数据就以DataFrame数据结构存储在内存中。

pandas数据行列删除,主要用到drop()和del函数,用法如下:

drop()

  • DataFrame.drop(labels,axis=0,level=None,inplace=False,errors=’raise’)
    • labels 接收string或array,代表要删除的行或列的标签(行名或列名)。无默认值
    • axis 接收0或1,代表操作的轴(行或列)。默认为0,代表行;1为列。
    • level 接收int或索引名,代表标签所在级别。默认为None
    • inplace 接收布尔值,代表操作是否对原数据生效,默认为False
    • errors errors='raise’会让程序在labels接收到没有的行名或者列名时抛出错误导致程序停止运行,errors='ignore’会忽略没有的行名或者列名,只对存在的行名或者列名进行操作。默认为‘errors=‘raise’’。

实例1:删除d列

df1 = df.drop(labels='d', axis=1)
print('删除d列前:\n', df)
print('删除d列后:\n', df1)

在这里插入图片描述
实例2:删除第一行

df2 = df.drop(labels=0)
print('删除前:\n', df)
print('删除列:\n', df2)

在这里插入图片描述
实例3:同时删除多行多列

df3 = df.drop(labels=['a', 'b'], axis=1) # 同时删除a,b列
df4 = df.drop(labels=range(2)) # 等价于df.drop(labels=[0,1])
print('删除前:\n', df)
print('删除多列(a,b):\n', df3)
print('删除多行(第1,2行):\n', df4)

在这里插入图片描述

df5 = df[df['c'] < 2]
df6 = df.drop(labels=range(2))  # 同时删除c列小于2的行
print('删除前:\n', df)
print('删除多行(c列小于2):\n', df6)

在这里插入图片描述

注意:(1)、删除列的操作时,axis参数不可省,因为axis默认为0(行);
(2)、没有加入inplace参数,默认不会对原来数据进行修改,需要将结果赋值给新的变量。

del

语法:del df[‘列名’]
此操作会对原数据df进行删除,且一次只能删除一列。
正确用法

del df['d']
print('原地删除d列后:\n', df)

在这里插入图片描述
错误用法:

del df[['a', 'b']]
print(df)

在这里插入图片描述

  • drop()相对于del()来说,灵活性更高,更为实用。

补全缺失值(NaN)

  • df.fillna(value=None,method=None,axis=None,inplace=False,limit=None)
    • value 标量或字典对象用于填充缺失值
    • method 插值方法 默认为“ffill”
    • axis 需填充的轴 默认为0
    • inplace 修改被调用的对象 而不是一个备份
    • limit 用于向前或向后填充时最大的填充范围

异常值

脏数据也包含不符合要求的数据,name对这块数据处理不能直接使用fillna填充。使用replace更加灵活。

  • df.replace(to_replace=None,value=None)
    • to_replace 去替换的值
    • value 替换的值

处理重复数据

判断重复值

  • df.duplicated(subset=None,keep=‘first’) 返回一个布尔值Series,默认反应的是每一行是否与之前出现过的行相同
    • subset 指定子列判断重复
    • keep 默认为first保留首个出现的 last保留最后出现的
      删除重复值
  • df.drop_duplicates(subset=None,keep=‘first’) 返回的是DataFrame 默认删除重复行
    • subset 指定子列判断重复
    • keep 默认为first保留首个出现的 last保留最后出现的

练习1

IMDB-Movie-Data.csv
根据给定数据绘制电影市场分布

练习2

读取FoodFacts.csv文件,对全球每个国家添加剂的使用进行分析。

离散化

离散化是把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。可以简单的理解为离散化就是将连续值进行分区间。

  • pd.cut(x,bins) 将连续数据x进行离散化
    • x 要进行离散化的数据
    • bins 分组
  • pd.value_counts(cates) 统计每个区间的数值分布

利用映射转换数据

需求:如下数据。进行分班

  • 一班:胡歌,小岳岳,林更新
  • 二班:金世佳,郭麒麟
data = {
		"names":["胡歌","金世佳","林更新","郭麒麟","小岳岳"],
		"grades":np.random.randint(1,100,size=5)
}
df = pd.DataFrame(data)

使用:df[“列标签”].map(“映射到的数据”)

重命名轴索引

需求:如下数据,将行索引名字全部转为大写

data = {
		"names":["bob","amy","cheney","jerry"]
		"grades":np.random.randint(60,100,size=4)
}
df2 = pd.DataFrame(np.random.randint(60,100,size=(4,2)),index=["bob","amy","cheney","jerry"])
df2

方法一:

  • 使用map函数映射 df.index.map(str.upper)
    • df.index.map(lambda x : x.upper)
    • columns同理

方法二:(推荐)

  • 使用df.rename 方法 df.rename(index,columns)
    • rename方法一:df.rename(index = str.lower,columns = str.upper)
    • rename方法二:df.rename(index = {“A”:“B”} , columns ={})
      • dict中的键值对必须一一对应
      • A是修改之前的名称 B是要修改的名称

向量化字符串函数

在这里插入图片描述
练习:读取 catNames2.csv ,找到所有的使用次数超过700并且名字的字符串的长度大于4的动物的名字

计算虚拟变量

分类变量转换为"虚拟"或"指标"矩阵是另一种用于统计建模或机器学习的转换操作。如果DataFrame中的一列有K个不同的值,则可以衍生出一个K列的值为1和0的矩阵或DataFrame。

  • pd.get_dummies() 将分类变量转换为"虚拟"或"指标"矩阵
    但是,如果说DataFrame中的一行属于多个类别,情况就会比较复杂。如下图
    在这里插入图片描述

练习

读取IMDB-Movie-Data.csv对其分类(Genre)这列转化为虚拟矩阵。

数据规整

索引与分层索引

索引

  • 查看索引:df.index
  • 指定索引:df.index = [,] 个数必须一致
  • 重新索引:df.reindex([,]) 无需个数一致,多出的会用NaN填充
  • 指定某一列作为index:df.set_index(“M”,drop=False)
  • 返回index的唯一值:df.set_insex(“M”).index.unique()
  • 重置索引: df.reset_index(inplace=True,drop=True)
    • inplace=False,默认该删除操作不改变原数据,而是返回一个执行删除操作后的新dataframe;
    • inplace=True,则会直接在原数据上进行删除操作,删除后无法返回。
    • drop=True就是把原来的索引index列去掉,重置index;
    • drop=False就是保留原来的索引,添加重置的index。

分层索引

分层索引是Pandas一个重要的特性,允许在一个轴上拥有多个索引层级。
在这里插入图片描述

df = pd.DataFrame({
	'a':range(7),
	'b':range(7,0,-1),
	'c':['one','one','one','two','two','two','two'],
	'd':list("hjklmno")
})

df.set_index(["c","d"])

Pandas从多个条件(AND,OR,NOT)中提取数据

使用Pandas从多个条件(AND,OR,NOT)中提取行的方法。
有以下2点需要注意:

  • &,|,〜的使用(and、or、not的错误)
  • 使用比较运算符时,请将每个条件括在括号中。
    df_and = df[(df['age'] < 35) & ~(df['state'] == 'NY')]
  • 运算符的优先级是NOT(〜),AND(&),OR(|)。因此,结果因顺序而异。

数据合并

数据合并也就是说将多个数据集拼接在一起,但是合并的方式主要分为:pandas.merge,pandas.concat,df.join。以下,我们来详细的介绍。

merge()

基于进行关联,是最常用的一种方法。函数为:

pd.merge(left,right,how='inner',on=None,left_on=None,right_on=None,left_index=False,right_index=False)
  • left:拼接左侧的DataFrame对象;
  • right:拼接右侧的DataFrame对象;
  • on:待关联的同名列名,存在于左右两个DataFrame对象中;
  • how:连接方式,inner(默认),其他可选:outer、left、right;
  • left_on:左侧DataFrame中用作连接键的列名;
  • right_on:右侧DataFrame中用作连接键的列;
  • left_index:将左侧的行索引用作其连接键;
  • right_index:将右侧的行索引用作其连接键;
"""
创建数组1
"""
polls = {"sites":["迈皋桥", "草场门", "浦口", "奥体中心", "仙林大学城"], 
        "AQI":[55, 75, 69, 74, 58], 
        "PM25":[30, 54, 47,40 ,27], 
        "SO2":[10, 15, 13, 17, 10]}

sites = {"names":["迈皋桥", "草场门", "浦口", "奥体中心", "玄武湖"], 
        "regions":["栖霞区", "鼓楼区", "浦口区", "建邺区", "玄武区"], 
        "weather":["晴", "晴", "多云", "阴", "晴"]}
        
# 读取数据集,把字典格式转变为DataFrame格式
df_polls = pd.DataFrame(polls)
df_sites = pd.DataFrame(sites)


"""
创建数组2
"""
# 定义左侧数据集
df_left = pd.DataFrame({"sites":["迈皋桥", "草场门", "浦口", "迈皋桥", "草场门", "浦口"], 
                       "date":["2020-12-08", "2020-12-08", "2020-12-08", "2020-12-07", "2020-12-07", "2020-12-07"],  
                       "AQI":[55, 75, 69, 45, 35, 53]})
# 定义右侧数据集
df_right = pd.DataFrame({"sites":["迈皋桥", "草场门", "迈皋桥", "草场门"], 
                        "date":["2020-12-08", "2020-12-08", "2020-12-09", "2020-12-09"], 
                        "weather":["晴",  "晴", "多云", "阴"]})

"""
创建数组3
"""
sites_with_index = pd.DataFrame({"regions":["栖霞区", "鼓楼区", "浦口区", "建邺区", "玄武区"]},
                                index=["迈皋桥", "草场门", "浦口", "奥体中心", "玄武湖"])

join()

join方法是基于index连接DataFrame。join连接方法有内连接,外连接,左连接和右连接,与merge一致。

"""
创建数组4
"""
polls_with_index = pd.DataFrame({"AQI":[55, 75, 69, 74, 58], 
                                 "PM25":[30, 54, 47,40 ,27], 
                                 "SO2":[10, 15, 13, 17, 10]}, 
                                index=["迈皋桥", "草场门", "浦口", "奥体中心", "仙林大学城"])

concat()

另外一种常用的数据整合方法是concat,即我希望按照某找方式把两个规整的数据集进行拼接。拼接原型函数非常简单:

pd.concat(objs,axis=0,join='outer',keys=None)
  • objs:带拼接的数据集,通常以列表的形式传入;
  • join:可选inner、outer,含义同merge函数;
  • keys:定义新的分组索引,用来区分传入的数据集
"""
创建数组5
"""
new_polls = {"sites":["迈皋桥", "草场门", "浦口", "奥体中心", "仙林大学城"], 
        "AQI":[65, 85, 79, 78, 78], 
        "PM25":[50, 74, 67,60 ,47], 
        "O2":[20, 35, 23, 37, 15]}
        
df_polls_new = pd.DataFrame(new_polls)

数据分组与聚合

数据包含在Series、DataFrame数据结构中,可以根据一个或多个键分离到各个组中。分组操作之后,一个函数就可以应用到各个组中,产生新的值。如下图则是简单的分组聚合过程。

key为指定分组的列

  • df.groupby(‘key’)
import pandas as pd
import numpy as np

df1 = pd.DataFrame(
    {
        "names":["菲菲","小可爱","mia","牛哥","老王","mia","狼人","药水哥","药水哥"],
        "classes":["一班","二班","三班"]*3,
        "grades":np.random.randint(60,100,size=9)
    }
)

df1

df1.groupby(by="classes")["grades"].mean()

groupy求取分组的个数

df1.groupby(by="classes").size()

聚合函数如下:

在这里插入图片描述

自定义聚合函数

实现步骤:

  • 自定义函数
  • 分组后通过agg或者aggregate进行聚合
def classes_ptp(x):
	return x.max()-x.min()

df1.groupby(by="classes")["grades"].age(classes_ptp)
df1.group(by="classes")["grades"].aggregate(classes_ptp)

分组块上应用函数

实现步骤:

  • 定义函数
  • 通过apply方法将函数应用到分组后的数组
def sort_df(df):
	return df.sort_values(by="grades")

df1.groupby(by="classes").apply(sort_df)

除了以上分组形式,还可以通过字典、series、函数进行分组

df2 = pd.DataFrame(
	np.random.randint(60,100,size=(5,3)),
	index=["菲菲","小可爱","mia","牛哥""老王"],
	columns=["语文","数学","英语"]
)
df2

pd按照某一列进行排序

  • pandas按照某一列进行排序,sort_values表示根据某一列排序 pd.sort_values(“xxx”,inplace=True) 表示pd按照xxx这个字段排序,inplace默认为False,如果该值为False,那么原来的pd顺序没变
data1 = pd.Series(np.random.randint(1,10,size = 5))
data1.sort_values()
data2 = pd.DataFrame({'ID':np.random.randint(1,10,size = 5),'AGE':np.random.randint(1,10,size = 5)})
data2.sort_values('ID',inplace=True)
  • pandas按照索引进行排序,sort_index。
data1 = pd.Series(np.random.randint(1,10,size = 5))
data1.sort_index()
data2 = pd.DataFrame({'ID':np.random.randint(1,10,size = 5),'AGE':np.random.randint(1,10,size = 5)})
data2.sort_index()

sort_value排序

df.sort_values(by='xxx', axis=0, ascending=True, inplace=False,kind='quicksort', na_position='last', ignore_index=False, key=None)

参数:

  • by – 指定列名(axis=0或者’index’)或索引值(axis=1者’columns’)
  • axis – 按行、按列,默认axis=0按指定列排序
  • ascending – 是否升序 默认为True
  • inplace – 是否修改原对象
  • kind – 排序算法 快排quicksort、归并mergesort、堆排序
  • heapsort、稳定排序stable,默认快排
  • na_position – {‘first’, ‘last’} 设定缺失值的显示位置
  • ignore_index – 排序后是否重置索引
  • key – 排序之前使用的函数 (version 1.1.0 后才有该参数)

时间序列

时间序列前言

时间序列数据在很多领域都是重要的结构化数据形式,比如:金融,神经科学,生态学,物理学。在多个时间点观测的数据形成了时间序列。时间序列可以是固定频率的,也可以是不规则的。

常见使用

  • 时间戳
  • 固定的时间区间
  • 时间间隔

时间序列基础

时间序列介绍

Pandas中的基础时间序列种类是由时间戳索引的Series,在Pandas外部通常表示为Python字符串或datatime对象。
注意

  • datetime对象可作为索引,时间序列DatetimeIndex
  • <M8[ns]类型为纳秒级时间戳
  • 时间序列里面每个元素为Timestamp对象

生成时间序列函数

  • pd.date_range(start=None,end=None,periods=None,freq=None,tz=None,normalize=False)
    • start 起始时间
    • end 结束时间
    • periods 固定时期
    • freq 日期偏移量(频率)
    • normalize 标准化为0的时间戳
d1 = pd.date_range(start="20200101",end="20200201")
d1

d2 = pd.date_range(start="20200101",end="20200201",periods=5)
d2

d3 = pd.date_range(start="20200101",periods=5,freq="10D")
d3

d4 = pd.date_range(start="2020-01-01 12:59:59",periods=5,freq="10D",normalize=True)
d4

关于频率设置如下:
在这里插入图片描述
具体可参考:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timeseries-offset-aliases

时间序列的索引及选择数据

ts = pd.Series(np.random.randint(1,100,size=800),index=pd.data_range("20180101",periods=800))
ts

# 选择2020的数据
ts['2020']

# 选择2020的一月份数据
ts['2020 01']

# 取2020年5月01至5月10的数据
ts['2020 05 01':'2020 05 10']

含有重复索引的时间序列

  • df.indexis_unique 检查索引是否唯一

移位日期

“移位”指的是将日期按时间向前移动或向后移动。Series和DataFrame都有一个shift方法用于进行简单的前向或后向移位,而不改变索引

ts.shift(2)	# 向前移动

ts.shift(-2)	# 向后移动

重采样

重采样介绍

重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,低频率转化为高频率为升采样

ts = pd.DataFrame(np.random.randint(100,200,size=100),index=pd.data_range(start="20200101",periods=100))
ts

ts.resample("M").mean()

以上为时间序列的基本内容。但是我们来看以下常见场景

df = pd.DataFrame(np.random.randint(1000,4000,size=(4,4)),index=[20200101,20200102,20200103,20200104],columns=["北京","上海","广州","深圳"])
df

转换为时间索引

该行索引类型并不是时间序列类型,所以我们想要使用时间序列的特性,就需要将其转为时间序列。通过pd.to_datetime(),其中的format参数可以调试时间序列的格式,常用如下:
在这里插入图片描述

时间索引提取年月日

import pandas as pd

list_of_dates = ['2019-11-20', '2020-01-02', '2020-02-05','2020-03-10','2020-04-16']
employees=['Hisila', 'Shristi','Zeppy','Alina','Jerry']
df = pd.DataFrame({'Joined date': pd.to_datetime(list_of_dates)}, index=employees)

df['Year'] = df['Joined date'].dt.year
df['Month'] = df['Joined date'].dt.month
df['Day'] = df['Joined date'].dt.day

# 转化为日期类型datetime64[ns]
df['Date'] = pd.to_datetime(df['Joined date'].dt.date)
print(df)

pd_to_datetime将时间戳转换日期格式问题

一、问题描述

data["date"] = pd.to_datetime(data["timestamp"],unit = "ms")

将时间戳数据转换成日期格式,使用的是pd_to_datetime进行转换,转化后 出现了不一致性,比真实时间少8小时。
在这里插入图片描述

二、原因分析

  • 查看pd_to_datetime文档,发现有一个utc的字段,来控制时区导致的

三、解决方式

df['time'] = pd.to_datetime(df['timestamp'], unit='ms') + pd.Timedelta(hours=8)

练习
统计出911数据中不同月份的电话次数
练习
北上广深与沈阳5个城市空气质量数据,绘制出北京的PM2.5随时间的变化情况

常遇问题集

问题1

如下图,没有显示删除后的数据。
在这里插入图片描述

原因1

这是因为 df.dropna() 在没有指定 inplace=True 的时候他是不改变原有数据的,也就是说实际上df并没有改变。

那此处的代码就是因为,没有改变df10本身,所以输出df10是没有任何变化的。

问题2

向量化字符串函数只适用于Series对象,而不适用于DataFrame奥~
在这里插入图片描述
注意:而且只能用于字符串,如果是数值要进行处理,则可使用apply进行应用

问题3

df_f = pd.DataFrame({
    'a':range(7),
    'b':range(7,0,-1),
    'c':['one','one','one','two','two','two','three'],
    'd':list("hjklmno")
})

df_f4 = df_f.set_index(["c","d"])

'''
         a  b
c     d      
one   h  0  7
      j  1  6
      k  2  5
two   l  3  4
      m  4  3
      n  5  2
three o  6  1

'''

# 取one,two两块
#print(df_f4.loc["one":"two"])
# 报错:pandas.errors.UnsortedIndexError: 'Key length (1) was greater than MultiIndex lexsort depth (0)'

#但用神奇索引可以正常取值
print(df_f4.loc[["one","two"]])
'''
c   d      
one h  0  7
    j  1  6
    k  2  5
two l  3  4
    m  4  3
    n  5  2

上课讲解时,只有 one,two 两块,所以使用 df_f4.loc[“one”:“two”] 获取数据时,没有问题。但是当添加一个 three 时候就会报错。

原因3

问题就在索引无序,而切片等操作要求有序。
解决这问题可用pd.sort_index()的方法来先给索引排序。之后就可切片。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值