【笔记】2022.06.20 python数据分析三大神器numpy、pandas、matplotlib

0. 引入案例

RIGHT Example

names = ['孙悟空', '李元芳', '白起', '狄仁杰', '达摩']
courses = ['语文', '数学', '英语']

import random

scores = [[random.randrange(60, 101) for _ in range(3)] for _ in range(5)]

print(scores)
# [[100, 97, 76], [91, 79, 66], [84, 78, 71], [87, 81, 96], [73, 71, 88]]


def mean(nums):
    """求均值"""
    return sum(nums) / len(nums)


def variance(nums):
    """求方差"""
    mean_value = mean(nums)
    return mean([(num - mean_value) ** 2 for num in nums])


def stddev(nums):
    """求标准差"""
    return variance(nums) ** 0.5


# 统计每个学生的考试平均分
for idx, name in enumerate(names):
    temp = scores[idx]
    avg_score = mean(temp)
    print(f'{
     name}考试平均分为:{
     avg_score:.1f}分')
    
'''
孙悟空考试平均分为:91.0分
李元芳考试平均分为:78.7分
白起考试平均分为:77.7分
狄仁杰考试平均分为:88.0分
达摩考试平均分为:77.3分
'''

# 统计每门课的最高分、最低分、标准差
for idx, course in enumerate(courses):
    temp = [scores[i][idx] for i in range(len(names))]
    max_score, min_score = max(temp), min(temp)
    print(f'{
     course}成绩最高分:{
     max_score}分')
    print(f'{
     course}成绩最低分:{
     min_score}分')
    print(f'{
     course}成绩标准差:{
     stddev(temp):.1f}分')

'''
语文成绩最高分:100分
语文成绩最低分:73分
语文成绩标准差:8.8分
数学成绩最高分:97分
数学成绩最低分:71分
数学成绩标准差:8.6分
英语成绩最高分:96分
英语成绩最低分:66分
英语成绩标准差:11.1分
'''

# 将学生及其考试成绩以行的方式输出(按平均分从高到低排序)
results = {
   name: temp for name, temp in zip(names, scores)}
sorted_keys = sorted(results, key=lambda x: mean(results[x]), reverse=True)
for key in sorted_keys:
    verbal, math, english = results[key]
    print(f'{
     key}:\t{
     verbal}\t{
     math}\t{
     english}')
    
'''
孙悟空:    100	97	76
狄仁杰:	87	81	96
李元芳:	91	79	66
白起:	84	78	71
达摩:	73	71	88
'''

1. 感性认知

Python数据分析三大神器

  1. Numpy - Numerical Python - ndarray - 保存数据,完成批量的运算和处理
  2. pandas - Panel Data Set - Series(一维数据) / DataFrame(二维数据) - 封装了数据分析需要的各种方法
  3. matplotlib - 绘制统计图表

1.1 Numpy

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 将list处理成ndarray对象
scores = np.array(scores)
print(scores)

'''
array([[100,  97,  76],
       [ 91,  79,  66],
       [ 84,  78,  71],
       [ 87,  81,  96],
       [ 73,  71,  88]])
'''

# 查看数据类型
type(scores)
# numpy.ndarray

# 按横向(学生)求平均值
np.round(scores.mean(axis=1), 1)
# array([91. , 78.7, 77.7, 88. , 77.3])

# 按竖向(学科)求最高分、最低分、标准差
scores.max(axis=0)
# array([100,  97,  96])
scores.min(axis=0)
# array([73, 71, 66])
np.round(scores.std(axis=0), 1)
# array([ 8.8,  8.6, 11.1])

1.2 pandas

scores_df = pd.DataFrame(data=scores, columns=courses, index=names)
scores_df

效果图:

在这里插入图片描述

# 计算平均分
np.round(scores_df.mean(axis=1), 1)
'''
孙悟空    91.00000
李元芳    78.66875
白起     77.66875
狄仁杰    88.00000
达摩     77.33125
dtype: float64
'''
# 添加平均分列到表中
scores_df['平均分']= scores_df.mean(axis=1)
scores_df

效果图:

在这里插入图片描述

# 写入Excel文件
scores_df.to_excel('考试成绩.xlsx')
# 改plt字体
plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False

# 将生成的图表改成矢量图
%config InlineBackend.figure_format='svg'

# 生成柱状图
scores_df.plot(kind='bar', y=['语文','数学','英语'])
# 旋转横轴的刻度
plt.xticks(rotation=0)
# 保存图表
plt.savefig('成绩柱状图.svg')
# 显示图表
plt.show()

效果图:
在这里插入图片描述

# 求学科最高分、最低分、平均分
scores_df.max()
'''
语文     100.0
数学      97.0
英语      96.0
平均分     91.0
dtype: float64
'''

scores_df.min()
'''
语文     73.0
数学     71.0
英语     66.0
平均分    77.3
dtype: float64
'''

scores_df.std()
'''
语文      9.874209
数学      9.602083
英语     12.361230
平均分     6.461656
dtype: float64
'''

2. Numpy


2.1 创建一维数组

# 方法一:通过array函数将list处理成ndarray对象
array1 = np.array([1, 2, 10, 20, 100])
array1
# array([  1,   2,  10,  20, 100])

type(array1)
# numpy.ndarray

# 方法二:指定一个范围创建数组对象
array2 = np.arange(1, 100, 2)
array2
'''
array([ 1,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33,35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99])
'''

# 方法三:指定范围和元素的个数创建数组对象
array3 = np.linspace(-5, 5, 101)
array3
'''
array([-5. , -4.9, -4.8, -4.7, -4.6, -4.5, -4.4, -4.3, -4.2, -4.1, -4. ,
       -3.9, -3.8, -3.7, -3.6, -3.5, -3.4, -3.3, -3.2, -3.1, -3. , -2.9,
       -2.8, -2.7, -2.6, -2.5, -2.4, -2.3, -2.2, -2.1, -2. , -1.9, -1.8,
       -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1. , -0.9, -0.8, -0.7,
       -0.6, -0.5, -0.4, -0.3, -0.2, -0.1,  0. ,  0.1,  0.2,  0.3,  0.4,
        0.5,  0.6,  0.7,  0.8,  0.9,  1. ,  1.1,  1.2,  1.3,  1.4,  1.5,
        1.6,  1.7,  1.8,  1.9,  2. ,  2.1,  2.2,  2.3,  2.4,  2.5,  2.6,
        2.7,  2.8,  2.9,  3. ,  3.1,  3.2,  3.3,  3.4,  3.5,  3.6,  3.7,
        3.8,  3.9,  4. ,  4.1,  4.2,  4.3,  4.4,  4.5,  4.6,  4.7,  4.8,
        4.9,  5. ])
'''

# 方法四:用随机生成元素的方法创建数组对象
# 随机小数
array4 = np.random.random(10)
array4
'''
array([0.74861994, 0.80263292, 0.54287411, 0.99088428, 0.27465232,
       0.4421258 , 0.34908231, 0.39729076, 0.11863797, 0.37728455])
'''

# 随机整数
array5 = np.random.randint(1, 10)
array5
# 5

# 随机正态分布
array6 = np.random.normal(0, 1, 50000)
array6
'''
array([-1.24165108, -0.07314869, -1.37729185, ..., -1.00691177,
        0.19568883,  0.43887128])
'''
# 生成直方图
plt.hist(array6, bins=24)
plt.show()

效果图:
在这里插入图片描述

2.2 创建二维数组

# 方法一:通过array函数将嵌套列表处理成二维数组
array8 = np.array(([1, 2, 3], [4, 5, 5], [7, 8, 9]))
array8
'''
array([[1, 2, 3],
       [4, 5, 5],
       [7, 8, 9]])
'''

# 方法二:通过对一维数组调形变成二维数组
temp= np.arange(1, 11)
array9 = temp.reshape((5, 2))
array9
'''
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10]])
'''

# 方法三;通过生成随机元素创建二维数组
array10 = np.random.randint(60, 101, (5, 3))
array10
'''
array([[71, 91, 67],
       [95, 71, 96],
       [90, 91, 92],
       [67, 83, 74],
       [95, 78, 60]])
'''

# 方法四:创建全0、全1、指定值的二维数组
array11 = np.zeros((5, 4), dtype='i8')
array11
'''
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]], dtype=int64)
'''

array12 = np.ones((5, 4), dtype='i8')
array12
'''
array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]], dtype=int64)
'''

array13 = np.full((5, 4), 100)
array13
'''
array([[100, 100, 100, 100],
       [100, 100, 100, 100],
       [100, 100, 100, 100],
       [100, 100, 100, 100],
       [100, 100, 100, 100]])
'''

# 方法五:创建单位矩阵
array14 = np.eye(5)
array14
'''
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])
'''

2.3 数组的索引和切片


2.3.1 普通用法

array10
'''
array([[71, 91, 67],
       [95, 71, 96],
       [90, 91, 92],
       [67, 83, 74],
       [95, 78, 60]])
'''

# 取指定元素
array10[1][2]
# 96
array10[1, 2]
# 96

# 取部分元素
array10[:3, :2]
'''
array([[71, 91],
       [95, 71],
       [90, 91]])
'''

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

总结:对多维数组的操作中,每做一次索引降一次维,而做切片不会降维。

2.3.2 特殊索引

# 花式索引(fancy index)
array2[[0, 1, 2, -3, -2, -1, -10]]
# array([ 1,  3,  5, 95, 97, 99, 81])

array10[[0, 1, 4], [0, 1, 2]]
# array([71, 71, 60])

# 布尔索引
array1[[False, True, False, True, False]]
# array([ 2, 20], dtype=uint64)

array2[array2 > 80]
# array([81, 83, 85, 87, 89, 91, 93, 95, 97, 99])

array16 = np.arange(1, 10)
array16[array16 % 2 !=0]
# array([1, 3, 5, 7, 9])
array16[(array16 > 5) & (array16 % 2 != 0)]
# array([7, 9])
array16[(array16 > 5) | (array16 % 2 != 0)]
# array([1, 3, 5, 6, 7, 8, 9])
array16[(array16 > 5) | ~(array16 % 2 != 0)]
# array([2, 4, 6, 7, 8, 9])

array10[array10 > 80]
# array([91, 95, 96, 90, 91, 92, 83, 95])

2.5 ndarray对象的方法

array1 = np.random.randint(10, 50, 10)
array1

# 求和
array1.sum
np.sum(array1)

# 求平均
array1.mean()
np.mean(array1)

# 求中位数
np.median(array1)

# 求最大值最小值
array1.max()
np.amax(array1)

array1.min()
np.amin(array1)

# 求极差(全距)
array1.ptp()
np.ptp(array1)

# 求方差
array1.var
np.var(array1)

# 求标准差
array1.std
np.std(array1)

# 求累计和
array1.cumsum()
np.cumsum(array1)

2.5.1 对上述描述性统计方法的补充说明:

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

2.5.2 用Excel实现上述功能

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

2.5.3 分位点和找异常值

在这里插入图片描述

def outliers_by_iqr(t_array, lower_points = 0.25, upper_points = 0.75, whis = 1.5):
    """iqr找异常值"""
    q1, q3 = np.quantile(t_array, [lower_points, upper_points])
    iqr = q3 - q1
    return t_array[(t_array < q1 - whis * iqr)|(t_array > q3 + whis * iqr)]

# 测试
array2[-1] = 15
outliers_by_iqr(array2)
# array([15])

2.5.4 Z-score找异常值

在这里插入图片描述

def outliers_by_zscore(array, threshold=3):
    """Z-score判定法检测离群点"""
    mu, sigma = array.mean(), array.std()
    return array[np.abs((array - mu) / sigma) > threshold]

# 把数组改长点,以使500显得突兀
# repeat()(会把相同元素放在一起)和tile()(按原本的顺序重复)
temp = np.repeat(array2[:-1], 100)
# append()和insert()添加
temp = np.append(temp, array2[-1])
temp = np.insert(temp, 0, array2[-1])
temp

outliers_by_zscore(temp)
# array([500, 500])

2.6 其他方法


2.6.1 all()/any

判断数组中是否所有元素都是True/判断数组是否有True的元素。


2.6.2 astype()方法

拷贝数组,并将数组中的元素转换为指定的类型。

array5 = array3.astype(np.float64)
array5.dtype
# dtype('float64')

2.6.3 dump()和load()方法

保存数组到文件中,可以通过NumPy中的load()函数从保存的文件中家在数据创建数组。

序列化:把对象处理成字符串(str)或字节串(bytes) —> 串行化/腌咸菜

反序列化:把字符串或字节串还原成对象 —> 反串行化

  • json模块:dump / dumps / load / loads —> 通用,跨语言

  • pickle模块:dump / dumps / load / loads —> 私有协议,其他语言无法反序列化

# 保存
with open('array3', 'wb') as file:
    array3.dump(file)

# 读取
with open('array3', 'rb') as file:
    array6 = np.load(file, allow_pickle=True)
array6

2.6.4 fill()方法

向数组中填充指定的元素。即数组中元素全部变成指定元素。


2.6.5 flatten()方法

将多维数组扁平化成一维数组

array7 = np.arange(1, 11).reshape(5, 2)
array7
'''
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10]])
'''

array7.flatten('C')
# array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])

array7.flatten('F')
# array([ 1,  3,  5,  7,  9,  2,  4,  6,  8, 10])

2.6.6 nonzero()方法

返回非0元素的索引


2.6.7 round()方法

对数组中的元素做四舍五入操作。


2.6.8 sort()方法

array8 = np.random.randint(1, 100, 10)
array8
# array([55, 98, 48, 98, 38,  5, 35, 36, 39, 87])

# 返回排序后的新数组
np.sort(array8)
# array([ 5, 35, 36, 38, 39, 48, 55, 87, 98, 98])
array8
# array([55, 98, 48, 98, 38,  5, 35, 36, 39, 87])

# 在原始数组上就地排序
array8.sort()
# 无返回值
array8
# array([ 8, 10, 12, 27, 28, 43, 45, 57, 65, 98])

2.6.9 transpose()和swapaxes()方法

交换数组指定的轴。

# 对于二维数组,transpose相当于实现了矩阵的转置
array7.transpose()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sprite.Nym

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值