资讯详情

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

0. 引入案例

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()
''' array([[ 1, 3, 5, 7, 9], [ 2, 4, 6, 8, 10]]) '''

# swapaxes交换指定的两个轴,顺序无所谓
array7.swapaxes(0, 1)
''' array([[ 1, 3, 5, 7, 9], [ 2, 4, 6, 8, 10]]) '''

2.6.10 tolist()方法

将数组转成Python中的list。不改变原数组。

array7.tolist()
# [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

2.7 其他常用函数

2.7.1 np.unique()

去重。

array9 = np.array([1,1,1,1,2,2,2,3,3,3])
array9
# array([1, 1, 1, 1, 2, 2, 2, 3, 3, 3])

np.unique(array9)
# array([1, 2, 3])

2.7.2 stack堆叠

array10 = np.array([[1,1,1], [2,2,2]])
array10
''' array([[1, 1, 1], [2, 2, 2]]) '''

array11 = np.array([[3,3,3,], [4,4,4,]])
array11
''' array([[3, 3, 3], [4, 4, 4]]) '''

# 水平方向(沿着1轴方向)的堆叠
np.hstack((array10, array11))
''' array([[1, 1, 1, 3, 3, 3], [2, 2, 2, 4, 4, 4]]) '''

# 垂直方向(沿着0轴方向)的堆叠
np.vstack((array10, array11))
''' array([[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]]) '''

# 沿着指定轴堆叠并升维
np.stack((array10, array11), axis=0)
''' array([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]) '''

np.stack((array10, array11), axis=1)
''' array([[[1, 1, 1], [3, 3, 3]], [[2, 2, 2], [4, 4, 4]]]) '''

2.7.3 concatenate合并

array12 = np.concatenate((array10, array11), axis=0)
array12
''' array([[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]]) '''

array13 = np.concatenate((array10, array11), axis=1)
array13
''' array([[1, 1, 1, 3, 3, 3], [2, 2, 2, 4, 4, 4]]) '''

2.7.4 split拆分

# 垂直方向(沿着0轴方向)的拆分
np.vsplit(array12, 2)
''' [array([[1, 1, 1], [2, 2, 2]]), array([[3, 3, 3], [4, 4, 4]])] '''

np.vsplit(array12, 4)
''' [array([[1, 1, 1]]), array([[2, 2, 2]]), array([[3, 3, 3]]), array([[4, 4, 4]])] '''

# 水平方向(沿着1轴方向)的拆分
np.hsplit(array12, 3)
''' [array([[1], [2], [3], [4]]), array([[1], [2], [3], [4]]), array([[1], [2], [3], [4]])] '''

# 沿着指定轴拆分
np.split(array13, 2)
''' [array([[1, 1, 1, 3, 3, 3]]), array([[2, 2, 

标签: le36sn08dno传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台