数据分析(二) - numpy

本文详细介绍了numpy库在Python中的使用,包括创建和修改数组、数据类型转换、数组运算、广播原则、轴操作、数组转置、读取数据、索引切片、数值修改、布尔索引、三元运算、数值裁剪、统计方法以及nan和inf的处理。内容涵盖了数组的创建、形状修改、数组与数字及数组间的运算、数据类型转换以及统计分析等多个方面。
摘要由CSDN通过智能技术生成

什么是numpy

一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库多用于在大型、多维数组上执行数值运算

numpy基础

numpy创建数组(矩阵)

np.array()
numpy创建数组测试:

import numpy as np

#使用numpy生成数组,得到numpt.ndarray数据类型
t1 = np.array([1,2,3])
print('t1',t1)
print(type(t1))

t2 = np.array(range(10))
print('t2',t2)

t3 = np.arange(10) #numpy自有的方法,快速生成一堆数字, 和range(n)方法一样
print('t3',t3)
#dtype numpy数组存储的数据类型
print('t3 dtype',t3.dtype)

t4 = np.arange(4,10,2)
print('t4', t4)

输出:
t1 [1 2 3]
<class 'numpy.ndarray'>
t2 [0 1 2 3 4 5 6 7 8 9]
t3 [0 1 2 3 4 5 6 7 8 9]
t3 dtype int32
t4 [4 6 8]

指定numpy数组的数据类型 array.astype()

numpy中常见的更多数据类型
在这里插入图片描述
改变numpy数组的数据类型:

array.astype(dtype)

numpy数据类型测试:

import numpy as np
import random

#numpy中的数据类型
t1 = np.array(range(1,4), dtype=float)
print(t1)
print(t1.dtype)

#numpy中的bool类型
t2 = np.array(range(0,4), dtype='bool')
print(t2)
print(t2.dtype)

#调整numpy array的数据类型
t3 = t2.astype('int8')
print(t3)
print(t3.dtype)

# numpy中的小数
t4 = np.array([random.random() for i in range(10)])
print(t4)
print(t4.dtype)

# 取小数
t5 = np.round(t4,2)
print(t5)

输出:
[1. 2. 3.]
float64
[False  True  True  True]
bool
[0 1 1 1]
int8
[0.81910089 0.12703546 0.08847865 0.23887472 0.68077415 0.36955078
 0.10936044 0.33791395 0.06766471 0.22993483]
float64
[0.82 0.13 0.09 0.24 0.68 0.37 0.11 0.34 0.07 0.23]

修改numpy数组的形状

array.reshape()
reshape()返回一个新的array,原始array不会改变。
array.flatten()
将数组展平为一维数组

import numpy as np 
t1 = np.arange(12)
print('t1',t1)
#查看numpy数组的形状
print('t1 shape',t1.shape)

t2 = np.array([[1,2,3],[4,5,6]])
print('t2', t2)
print('t2 shape',t2.shape)

#修改numpy数组的形状
t3 = t1.reshape((3,4))
print('t3',t3)
print('t3 shape',t3.shape)

#将数组变为一维数组
t4 = t3.reshape(-1)
print('t4', t4)
print('t4 shape', t4.shape)

#将数组展平
t5 = t3.flatten()
print('t5', t5)
print('t5 shape', t5.shape)

输出:
t1 [ 0  1  2  3  4  5  6  7  8  9 10 11]
t1 shape (12,)
t2 [[1 2 3]
 [4 5 6]]
t2 shape (2, 3)
t3 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
t3 shape (3, 4)
t4 [ 0  1  2  3  4  5  6  7  8  9 10 11]
t4 shape (12,)
t5 [ 0  1  2  3  4  5  6  7  8  9 10 11]
t5 shape (12,)

数组和数字的运算

将数组和数字进行运算的时候,numpy会将数组中的每一个元素和数字进行计算(numpy的广播机制)。

import numpy as np 
t1 = np.arange(24).reshape(4,6)
print(t1)
print(t1 + 2)
print(t1*4)
输出:
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
[[ 2  3  4  5  6  7]
 [ 8  9 10 11 12 13]
 [14 15 16 17 18 19]
 [20 21 22 23 24 25]]
[[ 0  4  8 12 16 20]
 [24 28 32 36 40 44]
 [48 52 56 60 64 68]
 [72 76 80 84 88 92]]

numpy数组和数组的计算

形状一样的numpy数组,对应位置元素进行计算。
若形状不一样的数组,如果某一个维度一样,则在某一个维度上进行计算。

import numpy as np 
t1 = np.arange(24).reshape((4,6))
t2 = np.arange(100,124).reshape((4,6))
t3 = np.arange(4).reshape((4,1))
t4 = np.arange(6).reshape((1,6))
print('t1:\n',t1)
print('t2:\n',t2)
print('t3:\n',t3)
print('t4:\n',t4)
print('t1+t2:\n',t1+t2)  #对应元素位置相加
print('t1-t3:\n',t1-t3)  #t1每一列减去t3
print('t2-t4:\n',t2-t4)  #t2每一行减去t4
print('t1*t2:\n',t1*t2)  #t1元素乘以t2对应元素

输出:
t1:
 [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
t2:
 [[100 101 102 103 104 105]
 [106 107 108 109 110 111]
 [112 113 114 115 116 117]
 [118 119 120 121 122 123]]
t3:
 [[0]
 [1]
 [2]
 [3]]
t4:
 [[0 1 2 3 4 5]]
t1+t2:
 [[100 102 104 106 108 110]
 [112 114 116 118 120 122]
 [124 126 128 130 132 134]
 [136 138 140 142 144 146]]
t1-t3:
 [[ 0  1  2  3  4  5]
 [ 5  6  7  8  9 10]
 [10 11 12 13 14 15]
 [15 16 17 18 19 20]]
t2-t4:
 [[100 100 100 100 100 100]
 [106 106 106 106 106 106]
 [112 112 112 112 112 112]
 [118 118 118 118 118 118]]
t1*t2:
 [[   0  101  204  309  416  525]
 [ 636  749  864  981 1100 1221]
 [1344 1469 1596 1725 1856 1989]
 [2124 2261 2400 2541 2684 2829]]

numpy数组的广播原则

在这里插入图片描述

轴 (axis)

轴在numpy中可以理解为方向,使用0,1,2…数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴。

有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值。

回顾np.arange(0,10).reshape((2,5)),reshpe中2表示0轴长度(包含数据的条数)为2, 1轴长度为5, 所以数组一共有2X5等于10个数据。

二维数组的轴:
在这里插入图片描述
三维数组的轴:
在这里插入图片描述

numpy数组的转置 (三种方法)

array.transpose()
array.T
array.swapaxes(1,0)

from struct import unpack
import numpy as np 
t = np.arange(24).reshape(4,6)
print('t:\n',t)
print('t.transpose():\n', t.transpose())
print('t.T:\n', t.T)
print('t.swapaxes(1,0):\n', t.swapaxes(1,0))

输出:
t:
 [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
t.transpose():
 [[ 0  6 12 18]
 [ 1  7 13 19]
 [ 2  8 14 20]
 [ 3  9 15 21]
 [ 4 10 16 22]
 [ 5 11 17 23]]
t.T:
 [[ 0  6 12 18]
 [ 1  7 13 19]
 [ 2  8 14 20]
 [ 3  9 15 21]
 [ 4 10 16 22]
 [ 5 11 17 23]]
t.swapaxes(1,0):
 [[ 0  6 12 18]
 [ 1  7 13 19]
 [ 2  8 14 20]
 [ 3  9 15 21]
 [ 4 10 16 22]
 [ 5 11 17 23]]

numpy读取本地数据

CSV:Comma-Separated Value,逗号分隔值文件。
显示:表格状态。
源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录。
由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据。

numpy从文本文件中读取数据。

np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
在这里插入图片描述
a.csv
在这里插入图片描述

import numpy as np 
data = np.loadtxt('d:/a.csv', delimiter=',', dtype = int, unpack = True)  #unpack 转置,将得到的numpy数组进行转置, delimiter是array分隔字符串。
print(data)
print(type(data))

输出:
[[ 1  2  3  4]
 [24 25 26 24]]
<class 'numpy.ndarray'>

numpy索引和切片

numpy中使用较多的功能。

索引和切片

import numpy as np 
t = np.arange(24).reshape(4,6)
print('t:\n',t)
#取连续多行
print('t[2:]:\n',t[2:])

#取不连续的多行
print('t[[0,2,3]]:\n',t[[0,2,3]])

#取连续多个列
print('t[:,1:]:\n',t[:,1:])

#取不连续的多个列
print('t[:,[0,3,5]]:\n',t[:,[0,3,5]])

#取某一个点
print('t[2,3]:\n', t[2,3])

#取多个不相邻的点
#选出来的结果是(0,0) (2,1) (2,3)
c = t[[0,2,2],[0,1,3]]
print(c)

输出:
t:
 [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
t[2:]:
 [[12 13 14 15 16 17]
 [18 19 20 21 22 23]]
t[[0,2,3]]:
 [[ 0  1  2  3  4  5]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
t[:,1:]:
 [[ 1  2  3  4  5]
 [ 7  8  9 10 11]
 [13 14 15 16 17]
 [19 20 21 22 23]]
t[:,[0,3,5]]:
 [[ 0  3  5]
 [ 6  9 11]
 [12 15 17]
 [18 21 23]]
t[2,3]:
 15
[ 0 13 15]

numpy中数值的修改

import numpy as np 
t = np.arange(24).reshape(4,6)
print('t:\n',t)

t[:,2:4] = 0
print(t)

输出:
t:
 [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
[[ 0  1  0  0  4  5]
 [ 6  7  0  0 10 11]
 [12 13  0  0 16 17]
 [18 19  0  0 22 23]]

numpy中的布尔索引

import numpy as np 
t = np.arange(24).reshape(4,6)
print('t:\n',t)

#t中小于10的替换成3
t[t<10] = 3
print(t<10)
print(t)

输出:
t:
 [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
[[ True  True  True  True  True  True]
 [ True  True  True  True False False]
 [False False False False False False]
 [False False False False False False]]
[[ 3  3  3  3  3  3]
 [ 3  3  3  3 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]

numpy中的三元运算符 np.where(t,num1,num2)

将numpy数组数值固定在num1-num2之间

np.where(t,num1,num2)
将t中小于t的替换为num1,大于等于t的替换为num2

import numpy as np 
t = np.arange(24).reshape(4,6)
print('t:\n',t)

#t中小于10的替换成0,大于等于10的赋值为10
t2 = np.where(t<10,0,10)
print(t2)

输出:
t:
 [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
[[ 0  0  0  0  0  0]
 [ 0  0  0  0 10 10]
 [10 10 10 10 10 10]
 [10 10 10 10 10 10]]

numpy中的clip(裁剪)np.clip(t,num1,num2)

np.clip(t,num1,num2)
将t中小于num1的替换为num1;大于num2的替换为num2

from cmath import nan
import numpy as np 
t = np.arange(24).reshape(4,6)
t = t.astype(float)
t[3,3:] = np.nan
print('t:\n',t)


#t中小于10的替换成10,大于等于10的替换18
#但是nan没有被替换,
t2 = t.clip(10,18)
print(t2)

输出:
t:
 [[ 0.  1.  2.  3.  4.  5.]
 [ 6.  7.  8.  9. 10. 11.]
 [12. 13. 14. 15. 16. 17.]
 [18. 19. 20. nan nan nan]]
[[10. 10. 10. 10. 10. 10.]
 [10. 10. 10. 10. 10. 11.]
 [12. 13. 14. 15. 16. 17.]
 [18. 18. 18. nan nan nan]]

numpy常用统计方法

np.sum() 求和
np.sum(t) 对所有元素进行求和 array.sum()
np.sum(t, axis = 0) 按行,对所有列进行求和 array.sum(axis = 0)
np.sum(t, axis = 1) 按列,对所有行进行求和 array.sum(axis = 1)

import numpy as np 
t = np.arange(24).reshape(4,6)
#对所有元素进行求和
r1 = np.sum(t)
#按行,对每列进行求和
r2 = np.sum(t,axis=0)
#按列,对每行进行求和
r3 = np.sum(t,axis=1)
print(r1)
print(r2)
print(r3)

输出:
276
[36 40 44 48 52 56]
[ 15  51  87 123]

np.mean() 求均值
np.mean(t) 求所有元素的均值 array.mean()
np.mean(t, axis = 0) 按行,对列求均值 array.mean(axis = 0)
np.mean(t, axis = 1) 按列,对行求均值 array.mean(axis = 1)

np.midian() 求中位数 只有全局方法np.midian()形式
np.midian(t)
np.median(t, axis = 0)
np.median(t, axis = 1)

np.max() 求最大值
np.min() 求最小值
np.ptp() 求最大值和最小值之差
np.std() 求标准差

【默认返回多维数组的全部的统计结果,如果指定axis则返回一个当前轴上的结果】
标准差是一组数据平均值分散程度的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值反映出数据的波动稳定情况,越大表示波动越大,越不稳定
在这里插入图片描述

numpy中的nan和inf

nan和inf的数据类型为float。

nan(NAN,Nan):not a number表示不是一个数字。
什么时候numpy中会出现nan:

  • 当我们读取本地的文件为float的时候,如果有缺失,就会出现nan
  • 当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大);

inf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷
什么时候回出现inf包括(-inf,+inf)

  • 比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)。

统计数组中有多少nan

from cmath import nan
import numpy as np 
t = np.arange(24).reshape(4,6)
t = t.astype(float)
t[3,3:] = np.nan

#方法一:通过t!=t判断
r = t!=t  # np.nan !=- np.nan 所以遇到nan t!=t 相应位置会返回True
print(r)
count = np.count_nonzero(r) # 统计t!=t的非零个数就是nan的个数
print(count)

#方法二:通过np.isnan判断
r = np.isnan(t)
count = np.count_nonzero(r)
print()

输出:
[[False False False False False False]
 [False False False False False False]
 [False False False False False False]
 [False False False  True  True  True]]
3
3

numpy中nan的注意点

在这里插入图片描述

替换array中的nan

在一组数据中单纯的把nan替换为0,合适么?会带来什么样的影响?

比如,全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行。

import numpy as np 

def fill_array(t):
    for i in range(t.shape[1]):
        temp_col = t[:,i] #当前的一列
        num_nan = np.count_nonzero(temp_col != temp_col)
        if num_nan != 0:
            #选中当前一列不为nan的array
            temp_col_not_nan = temp_col[temp_col == temp_col] 
            #当前一列不为nan的array的均值
            mean = temp_col_not_nan.mean() 
            #将temp_col的nan位置替换为均值
            temp_col[np.isnan(temp_col)] = mean 
    return t

if __name__ == '__main__':
    t = np.arange(24).reshape(4,6).astype('float')
    t[1,2:] = np.nan
    print(t)
    fill_t = fill_array(t)
    print(fill_t)

输出:
[[ 0.  1.  2.  3.  4.  5.]
 [ 6.  7. nan nan nan nan]
 [12. 13. 14. 15. 16. 17.]
 [18. 19. 20. 21. 22. 23.]]
[[ 0.  1.  2.  3.  4.  5.]
 [ 6.  7. 12. 13. 14. 15.]
 [12. 13. 14. 15. 16. 17.]
 [18. 19. 20. 21. 22. 23.]]    

统计、绘图

英国和美国各自youtube1000的数据结合之前的matplotlib绘制出各自的评论数量的直方图。

针对读取的数据差距特别大,可以选择使用numpy的布尔索引,过滤掉过大或者过小的数据,以更直观的反应数据。

import numpy as np 
from matplotlib import pyplot as plt
path1 = 'GB_video_data_numbers.csv'
path2 = 'US_video_data_numbers.csv'

t_gb = np.loadtxt(path1, delimiter = ',', dtype = 'int')

#取评论数据
t_gb_comments = t_gb[:,-1]

#选择比5000小的数据
t_gb_comments = t_gb_comments[t_gb_comments<5000]

max = t_gb_comments.max()
min = t_gb_comments.min()

#设置组组距
d = 100
bin_nums = int((max-min)/d)

#设置图像大小
fig = plt.figure(figsize=(20,8), dpi = 80)

#绘制直方图
plt.hist(t_gb_comments,bins=bin_nums)

#展示
plt.show()

结果:
采用numpy的布尔索引过滤掉>5000的值,直方图x轴数据在0-5000之间。组距根据可视化结果动态调整为d = 100,bins = (max(t)-min(t))/d。
在这里插入图片描述
希望了解英国的youtube中视频的评论数和喜欢数的关系,应该如何绘制改图?

from turtle import width
import numpy as np 
from matplotlib import pyplot as plt
path1 = 'GB_video_data_numbers.csv'
path2 = 'US_video_data_numbers.csv'

t_uk = np.loadtxt(path1, delimiter = ',', dtype = 'int')

#取评论数据
t_uk_comments = t_uk[:,-1]
#取用户喜欢数据
t_uk_like = t_uk[:,1]

#选择喜欢数量比5e5小的
t_uk_comments_ = t_uk_comments[t_uk_like<=5e5]
t_uk_like_ = t_uk_like[t_uk_like<=5e5]

#设置图像大小
fig = plt.figure(figsize=(20,8), dpi = 80)

#绘制直方图
plt.scatter(t_uk_like_, t_uk_comments_)

#展示
plt.show()

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

numpy数组的拼接

np.vstack((t1,t2)) #垂直拼接
np.hstack((t1,t2)) #水平拼接

在这里插入图片描述
数组水平或者竖直拼接很简单,但是拼接之前应该注意什么?
竖直拼接的时候:每一列代表的意义相同。
如果每一列的意义不同,这个时候应该交换某一组的数的列,让其和另外一类相同。
如何交换某个数组的行或者列呢?
在这里插入图片描述
测试数组拼接:

from turtle import width
import numpy as np 
from matplotlib import pyplot as plt
uk_data = 'GB_video_data_numbers.csv'
us_data = 'US_video_data_numbers.csv'

uk_data = np.loadtxt(uk_data, delimiter = ',', dtype = 'int')
us_data = np.loadtxt(us_data, delimiter = ',', dtype = 'int')

#构造全0全1数组
zeros_data = np.zeros((uk_data.shape[0],1)).astype(int)
ones_data = np.ones((us_data.shape[0],1)).astype(int)

uk_data = np.hstack((uk_data, zeros_data))
us_data = np.hstack((us_data, ones_data))

final_data = np.vstack((uk_data, us_data))
print(final_data)

结果:
[[7426393   78240   13548     705       0]
 [ 494203    2651    1309       0       0]
 [ 142819   13119     151    1141       0]
 ...
 [ 142463    4231     148     279       1]
 [2162240   41032    1384    4737       1]
 [ 515000   34727     195    4722       1]]

numpy数组中的其它方法

  • 获取最大值最小值的位置
    np.argmax(t,axis=0)
    np.argmin(t,axis=1)
  • 创建一个全0的数组: np.zeros((3,4))
  • 创建一个全1的数组:np.ones((3,4))
  • 创建一个对角线为1的正方形数组(方阵):np.eye(3)

numpy生成随机数:
np.random()
在这里插入图片描述

  1. 均匀分布 np.random.rand(shape) 浮点数:0-1
    在相同的大小范围内的出现概率是等可能的。
    在这里插入图片描述
    生成均匀分布随机数测试:
from turtle import width
import numpy as np 
from matplotlib import pyplot as plt
data = np.random.rand(1000)
plt.hist(data)
plt.show()
print(data)

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

  1. 正态分布 np.random.randn(shape)
    呈钟型,两头低,中间高,左右对称。
    在这里插入图片描述
    生成正态分布随机数测试:
from turtle import width
import numpy as np 
from matplotlib import pyplot as plt
data = np.random.randn(1000)
plt.hist(data)
plt.show()
print(data)

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值