(没写完)[第11天] Python Pandas 数据分析 速通爆肝
数据集下载
下载地址:晚点更新
Pandas 介绍
Pandas是基于Numpy构建的。含有使数据分析工作变得更快更简单的高级数据结构和操作工具。它提供了大量高级的数据结构和对数据处理的方法。pandas 有两个主要的数据结构:Series 和 DataFrame。
描述性分析
描述性分析用于描述定量数据的整体情况,例如研究消费者对于某商品的购买意愿情况,可用到描述性分析对样本的年龄、收入、消费水平等各指标进行初步分析,以了解掌握消费者总体的特征情况。
描述分析应用场景
通过描述性分析计算数据的集中性特征(平均值)和波动性特征(标准差值),以了解数据的基本情况。因此在研究中经常是首先进行描述性分析,再次基础之上再进行深入的分析。
描述性分析还可用于查看数据是否有异常情况(最小值或最大值查看),比如数据中出现-2,-3等异常情况。
常见的描述指标
- 最大值、最小值可用来检验数据是否存在异常情况。
- 平均值、中位数是用于描述数据的集中趋势指标。
- 标准差是用于描述数据的离散趋势指标。如果比较单位不同(或数值相差太大)的两组数据时,采用变异系数比较离散程度。
- 峰度和偏度通常用于判断数据正态性情况,峰度的绝对值越大,说明数据越陡峭,峰度的绝对值大于3,意味着数据严重不正态。同时偏度的绝对值越大,说明数据偏斜程度越高,偏度的绝对值大于3,意味着严重不正态(可通过正态图查看数据正态性情况)
其他说明
1、一般采用平均值加标准差来描述数据的整体情况。
2、当数据呈现严重偏态时,采用中位数描述数据的整体水平情况,而不是平均值。
3、除了使用描述性分析外,也建议使用箱线图直观展示数据分布情况。
Series和DataFrame
Series
Series是一种类似于一维数组的对象。它由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。可以把它理解为一组带索引的数组
。
将Python 字典转换成Series
# ^ 将 Python 字典转换成 Series 对象
dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
obj = pd.Series(dic)
print(obj)
当没有显示指定索引的时候,Series 自动以 0 开始,步长为 1 为数据创建索引。
通过 index 参数显示指定索引
# ^ 通过 index 参数显示指定索引
obj2 = pd.Series([4, 5, 6, 7], index=['a', 'b', 'c', 'd'])
print(obj2)
对于 Series 对象里的单个数据来说,和普通数组一样,根据索引获取对应的数据或重新赋值
不过你还可以传入一个索引的数组来获取数据或未数据重新赋值
# ^ 获取数据 修改数据
print("获取 a=", obj2['a'])
print("获取 a、c Series\n", obj2[['a', 'c']])
# @ 修改数据
obj2['a'] = 10
obj2[['b', 'c']] = 20
print(obj2)
想要单独获取 Series 对象的索引或者数组内容的时候,可以使用 index 和 values 属性
# ^ 单独获取 Series 对象的索引或者数组内容的时候,可以使用 index 和 values 属性
print(obj2.index)
print(obj2.values)
# ^ 对 Series 对象的运算(索引不变)
print("Series 对象的运算")
obj3 = pd.Series([10, 20, 30, 40])
print(obj3*2)
print(obj3+1)
print(obj3[obj3 < 30])
print(obj3[obj3 > 10])
Dataframe
DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame既有行索引也有列索引
,它可以被看做由Series组成的字典
(共同用一个索引)。
例如将一个由 NumPy 数组组成的字典转换成 DataFrame 对象
# ! Dataframe
# ^ 将numpy数组字典转换成dataframe对象
data = {'name': ['小王', '小刘', '小能', '小张'], 'age': [30, 40, 20, 30], 'gender': ['m', 'm', 'm', 'f']}
frame = pd.DataFrame(data)
print(frame)
指定列的顺序
# ^ 指定列的顺序
frame = pd.DataFrame(data, columns=['name', 'gender', 'age'])
print(frame)
如果传入的列名找不到,它不会报错,而是产生一列 NA 值
# ^ 如果传入的列名找不到,它不会报错,而是产生一列 NA 值:
frame = pd.DataFrame(data, columns=['name', 'gender', 'age', 'weight'])
print(frame)
DataFrame 不仅可以以字典索引的方式获取数据,还可以以属性的方法获取
# ^ DataFrame 不仅可以以字典索引的方式获取数据,还可以以属性的方法获取
print(frame['name'])
print(frame.name)
修改数据
# ^ 修改列的数据
frame['weight'] = 60
print(frame)
# @ 删除一列
del frame['weight']
print(frame)
什么是NaN数据
在能够使用大型数据集训练学习算法之前,我们通常需要先清理数据。也就是说,我们需要通过某个方法检测并更正数据中的错误。虽然任何给定数据集可能会出现各种糟糕的数据,例如离群值或不正确的值,但是我们几乎始终会遇到的糟糕数据类型是缺少值。Pandas 会为缺少的值分配 NaN 值
。
处理NaN数据
统计NaN个数
import pandas as pd
import numpy as np
# ^ 创建一个字典数组
items2 = [{'bikes': 20, 'pants': 30, 'watches': 35, 'shirts': 15, 'shoes': 8, 'suits': 45},
{'watches': 10, 'glasses': 50, 'bikes': 15, 'pants': 5, 'shirts': 2, 'shoes': 5, 'suits': 7},
{'bikes': 20, 'pants': 30, 'watches': 35, 'glasses': 4, 'shoes': 10}]
# ^ 创建一个dataFrame对象,指定索引
store_items = pd.DataFrame(items2, index=['store 1', 'store 2', 'store 3'])
print(store_items)
可以看到有缺省的值被替换成了NaN,创建的 DataFrame 具有 3 个 NaN 值:商店 1 中有一个,商店 3 中有两个。但是,如果我们向 DataFrame 中加载非常庞大的数据集,可能有数百万条数据,那么就不太容易直观地发现 NaN 值的数量。对于这些情形,我们结合使用多种方法来计算数据中的 NaN 值的数量。以下示例同时使用了 .isnull()
和 sum()
方法来计算我们的 DataFrame 中的 NaN 值的数量。
# ^ 计算 dataframe 有多少 NaN 值
x = store_items.isnull().sum().sum()
# @ 第一次sum()算出各个列有几个,第二次算出全部
print('共有NaN值:', x)
# 共有NaN值: 3
在上述示例中,.isnull()
方法返回一个大小和 store_items
一样的布尔型 DataFrame,并用 True
表示具有 NaN
值的元素,用 False
表示非 NaN 值的元素。
# ^ isnull()方法返回一个大小和store_items一样的布尔型 DataFrame
frame = store_items.isnull()
print(frame)
在 Pandas 中,逻辑值 True
的数字值是 1,逻辑值 False
的数字值是 0。因此,我们可以通过数逻辑值 True
的数量数出 NaN
值的数量。为了数逻辑值 True
的总数,我们使用 .sum()
方法两次。要使用该方法两次,是因为第一个 sum() 返回一个 Pandas Series,其中存储了列上的逻辑值 True
的总数,如下所示:
数非 NaN 值的数量可以使用
.count()
方法
# ^ 数非 NaN 值的数量。可以使用 .count() 方法
print(store_items.count())
处理NaN值
我们有两种选择,可以删除或替换 NaN
值
axis = 0
,.dropna(axis)
方法将删除包含 NaN 值的任何行,如果 axis = 1
,.dropna(axis)
方法将删除包含 NaN
值的任何列。
# ! 处理NaN
# ^ 删除含NaN的行
frame = store_items.dropna(axis=0) # inplace = True 对结构直接进行修改
print(frame)
# ^ 删除含NaN的列
frame = store_items.dropna(axis=1)
print(frame)
注意,.dropna()
方法不在原地地删除具有 NaN
值的行或列。也就是说,原始 DataFrame 不会改变。你始终可以在 dropna()
方法中将关键字 inplace 设为 True
,在原地删除目标行或列。
可以选择将所有 NaN 值替换为 0。可以使用 .fillna()
方法
# @ 替换NaN的值
# ^ 把所有NaN的值替换为0
frame = store_items.fillna(0)
print(frame)
我们还可以使用 .fillna()
方法将 NaN
值替换为 DataFrame 中的上个值,称之为前向填充。在通过前向填充替换 NaN
值时,我们可以使用列或行中的上个值。.fillna(method = 'ffill', axis)
将通过前向填充 (ffill)
方法沿着给定 axis
使用上个已知值替换 NaN
值。
# ^ 把一行所有的NaN的值填充为上一行的值
frame = store_items.fillna(method='ffill', axis=0)
print(frame)
# ^ 把一行所有的NaN的值填充为前一列的值
frame = store_items.fillna(method='ffill', axis=1)
print(frame)
同样,你可以选择用 DataFrame 中之后的值替换 NaN
值,称之为后向填充。.fillna(method = 'backfill', axis)
将通过后向填充 (backfill)
方法沿着给定 axis
使用下个已知值替换 NaN
值。和前向填充一样,我们可以选择使用行值或列值。
# ^ 向后填充
frame = store_items.fillna(method='backfill', axis=0)
print(frame)
注意,.fillna()
方法不在原地地替换(填充)NaN
值。也就是说,原始 DataFrame 不会改变。你始终可以在 fillna()
函数中将关键字 inplace 设为 True
,在原地替换 NaN
值。
我们还可以选择使用不同的插值方法替换
NaN
值。例如,.interpolate(method = 'linear', axis)
方法将通过 linear
插值使用沿着给定 axis
的值替换 NaN
值。
# ^ 使用线性插值替换
frame = store_items.interpolate(method='linear', axis=1)
print(frame)
什么是聚合数据
合并来自不同数据源的数据,强调把分散在不同地方关于同一对象的不同说法合并起来,得到此对象的更为完整的信息。
合并来自不同数据源的数据
pandas 读取 csv
csv 介绍
逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。
read_csv 函数解析
read_csv(filepath_or_buffer,sep,header,names,skiprows,na_values,encoding,nrows)
按指定格式读取csv文件.
filepath_or_buffer:字符串,表示文件路径;
sep: 字符串,指定分割符,默认是',';
header:数值, 指定第几行作为列名(忽略注解行),如果没有指定列名,默认header=0; 如果指定了列名header=None;
names: 列表,指定列名,如果文件中不包含header的行,应该显性表示header=None.
skiprows:列表,需要忽略的行数(从0开始),设置的行数将不会进行读取.
na_values:列表,设置需要将值替换成NAN的值,pandas默认NAN为缺省,可以用来处理一些缺省,错误的数值.
encoding:字符串,用于unicode的文本编码格式.例如,"utf-8"或"gbk"等文本的编码格式.
nrows:需要读取的行数.
to_csv 函数解析
to_csv(path_or_buf,sep,na_rep,columns,header,index)
path_or_buf:字符串,文件名,文件具体,相对路径,文件流等;
sep:字符串,文件分割符号;
na_rep:字符串,将NaN转换为特定值;
columns:列表,选择部分列写入;
header:None,写入时忽略列名;
index:False则选择不写入索引,默认为True.
csv 库(扩展)
csv.reader(csvfile, dialect=‘excel’, **fmtparams)
csv.writer(csvfile, dialect=‘excel’, **fmtparams)
csvfile,必须是支持迭代(Iterator)的对象,可以是文件(file)对象或者列表(list)对象,如果是文件对
象,打开时需要加"b"标志参数。
qdialect,编码风格,默认为excel的风格,也就是用逗号(,)分隔,dialect方式也支持自定义
fmtparam,格式化参数,用来覆盖之前dialect对象指定的编码风格。
代码
import pandas as pd
import numpy as np
import os
# ^ 获取当前终端目录
path = os.getcwd()
# ^ 获取当前文件目录
path = os.path.dirname(__file__)
# ^ 读取 csv 操作
df = pd.read_csv(path+r'\iris.csv', header=None, names=['花蕾长', '花蕾宽', '花瓣长', '花瓣宽', '类别'])
"""
函数解析:
read_csv(filepath_or_buffer,sep,header,names,skiprows,na_values,encoding,nrows)
按指定格式读取csv文件.
filepath_or_buffer:字符串,表示文件路径;
sep: 字符串,指定分割符,默认是',';
header:数值, 指定第几行作为列名(忽略注解行),如果没有指定列名,默认header=0; 如果指定了列名header=None;
names: 列表,指定列名,如果文件中不包含header的行,应该显性表示header=None.
skiprows:列表,需要忽略的行数(从0开始),设置的行数将不会进行读取.
na_values:列表,设置需要将值替换成NAN的值,pandas默认NAN为缺省,可以用来处理一些缺省,错误的数值.
encoding:字符串,用于unicode的文本编码格式.例如,"utf-8"或"gbk"等文本的编码格式.
nrows:需要读取的行数.
"""
# @ 输出前三项数据
print(df.head(3))
# ^ 写入 csv 操作
filePath = path + r'\test.csv'
data = {
'name': ['小王', '小张', '小刘'],
'age': [10, 20, 30]
}
# @ 将字典转换成DataFrame数据结构类型
df = pd.DataFrame(data)
# @ 将DataFrame结构保存为csv文件
df.to_csv(filePath)
"""
函数解析:
to_csv(path_or_buf,sep,na_rep,columns,header,index)
path_or_buf:字符串,文件名,文件具体,相对路径,文件流等;
sep:字符串,文件分割符号;
na_rep:字符串,将NaN转换为特定值;
columns:列表,选择部分列写入;
header:None,写入时忽略列名;
index:False则选择不写入索引,默认为True.
"""
Pandas 读取 TSV
什么是 TSV
TSV 是Tab-separated values的缩写,即制表符分隔值。
Python的csv模块准确的讲应该叫做dsv模块,因为它实际上是支持范式的分隔符分隔值文件(DSV,delimiter-separated values)的。
delimiter参数值默认为半角逗号,即默认将被处理文件视为CSV。
当delimiter='\t'
时,被处理文件就是TSV。
代码
import pandas as pd
import os
# ^ 获取当前文件目录
path = os.path.dirname(__file__)
# ^ 读取 tsv 操作
# IMPORTANT 这里用到了 sep = '\t'
df = pd.read_csv(path+'/realEstate_trans.tsv', sep='\t')
print(df.head(3))
# ^ 保存 tsv 操作
filePath = path + r'\test.tsv'
data = {
'name': ['小王', '小张', '小刘'],
'age': [10, 20, 30]
}
# @ 转换成 dataframe 结构
df = pd.DataFrame(data)
# @ 添加间隔符\t,禁止保存索引
df.to_csv(filePath, sep='\t', index=False)
Pandas 读取 JSON
json存在的目的是为了跨语言交换数据
read_json 函数
read_json(path_or_buf,orient,encoding,numpy)
常见参数解析:
path_or_buf:字符串,表示文件路径;
orient:指示预期的JSON字符串格式.可以to_json()使用相应的方向值生成兼容的JSON字符串.一组可能的方向是:
'split' : dict like {index -> [index], columns -> [columns], data -> [values]}
'records' : list like [{column -> value}, ... , {column -> value}]
'index' : dict like {index -> {column -> value}}
'columns' : dict like {column -> {index -> value}}
'values' : just the values array
encoding:字符串,默认为'utf-8';
numpy:布尔值,默认为False,直接解码为numpy数组.仅支持数字数据,但支持非数字列和索引标签.另请注意,如果numpy = True,则每个术语的JSON顺序必须相同.
to_json 函数
to_json(path_or_buf,orient,encoding,index)
前三个参数和read_json()里的一样
index:False则选择不写入索引,默认为True.
代码
import pandas as pd
import os
# ^ 获取当前文件目录
path = os.path.dirname(__file__)
# ^ 读取 json 操作
df = pd.read_json(path+'/films.json')
"""
read_json(path_or_buf,orient,encoding,numpy)
常见参数解析:
path_or_buf:字符串,表示文件路径;
orient:指示预期的JSON字符串格式.可以to_json()使用相应的方向值生成兼容的JSON字符串.一组可能的方向是:
'split' : dict like {index -> [index], columns -> [columns], data -> [values]}
'records' : list like [{column -> value}, ... , {column -> value}]
'index' : dict like {index -> {column -> value}}
'columns' : dict like {column -> {index -> value}}
'values' : just the values array
encoding:字符串,默认为'utf-8';
numpy:布尔值,默认为False,直接解码为numpy数组.仅支持数字数据,但支持非数字列和索引标签.另请注意,如果numpy = True,则每个术语的JSON顺序必须相同.
"""
print(df.head(3))
# ^ 写入 json 操作
filePath = path + r'\test.tsv'
data = {
'name': ['小王', '小张', '小刘'],
'age': [10, 20, 30]
}
# @ 转换成 dataframe 结构
df = pd.DataFrame(data)
# @ 添加间隔符\t,禁止保存索引
df.to_json(filePath)
"""
to_json(path_or_buf,orient,encoding,index)
前三个参数和read_json()里的一样
index:False则选择不写入索引,默认为True.
"""
loads、dumps(扩展)
先放放