numpy学习
什么是numpy
一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算。
numpy创建数组(矩阵)
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
print(type(t2))
t3 = np.arange(4,10,2)
print(t3)
print(type(t3))
print(t3.dtype)
运行结果:
[1 2 3]
<class 'numpy.ndarray'>
[0 1 2 3 4 5 6 7 8 9]
<class 'numpy.ndarray'>
[4 6 8]
<class 'numpy.ndarray'>
int32
默认整数类型np.int_是C long,但是C long在win64中是int32.
numpy中常见的更多数据类型
数据类型的操作
import numpy as np
import random
t4 = np.array(range(1,4),dtype=float)
print(t4)
print(t4.dtype)
t5 = np.array([1,0,1,1,0],dtype=bool)
print(t5)
print(t5.dtype)
t6 = t5.astype("int8")
print(t6)
print(t6.dtype)
t7 = np.array([random.random() for i in range(10)])
print(t7)
print(t7.dtype)
print(np.round(t7,3))
运行结果:
[1. 2. 3.]
float64
[ True False True True False]
bool
[1 0 1 1 0]
int8
[0.40965587 0.65607682 0.55963194 0.17005824 0.97233548 0.20681428
0.37630063 0.45185797 0.40072167 0.32030872]
float64
[0.41 0.656 0.56 0.17 0.972 0.207 0.376 0.452 0.401 0.32 ]
数组的形状
查看数组的形状:
import numpy as np
t1 = np.array(range(10))
print(t1)
print(t1.shape)
print("#######################################")
t2 = np.array([[0,1,2,3,4],[5,6,7,8,9]])
print(t2)
print(t2.shape)
print("#######################################")
t3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(t3)
print(t3.shape)
print("#######################################")
运行结果:
[0 1 2 3 4 5 6 7 8 9]
(10,)
[[0 1 2 3 4]
[5 6 7 8 9]]
(2, 5)
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
(2, 2, 3)
修改数组的形状:
import numpy as np
t4 = np.array(range(12))
print(t4)
print(t4.reshape((3,4)))
print("#######################################")
t5 = np.arange(24).reshape((2,3,4))
print(t5)
print(t5.reshape((4,6)))
print(t5.flatten())
运行结果:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[[ 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 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
数组和数的计算
广播原则
可以把维度指的是shape所对应的数字个数。
shape为(3,3,3)的数组能够和(3,2)的数组进行计算么?
不可以
shape为(3,3,2)的数组能够和(3,2)的数组进行计算么?、
可以
所以假设有两个数组,第一个的维度是(x_1, y_1, z_1),另一个数组的维度是(x_2, y_2, z_2),要判断这两个数组能不能进行计算,可以用如下方法来判断:
if z_1 == z_2 or z_1 == 1 or z_2 == 1:
if y_1 == y_2 or y_1 == 1 or y_2 == 1:
if x_1 == x_2 or x_1 == 1 or x_2 == 1:
可以运算
else:
不可以运算
else:
不可以运算
else:
不可以运算
这里需要注意:(3,3,2)和(3,2)是可以运算的,因为对于二维数组(3,2)也可以表示为(1,3,2),套用上述的规则是完全适用的,同理:(4,2,5,4)和(2,1,4)也是可以进行运算的。
轴(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读取本地数据
读取文件:CSV:Comma-Separated Value,逗号分隔值文件
显示:表格状态
源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录
由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据,为了方便教学,我们会经常操作csv格式的文件,但是操作数据库中的数据也是很容易的实现的。
np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
示例:现在这里有一个英国和美国各自youtube1000多个视频的点击,喜欢,不喜欢,评论数量([“views”,“likes”,“dislikes”,“comment_total”])的csv,运用刚刚所学习的只是,我们尝试来对其进行操作。
import numpy as np
us_file_path = "./youtube_video_data/US_video_data_numbers.csv"
uk_file_path = "./youtube_video_data/GB_video_data_numbers.csv"
t1 = np.loadtxt(us_file_path,delimiter=",",dtype="int",unpack=True)
t2 = np.loadtxt(us_file_path,delimiter=",",dtype="int")
print(t1)
print("*"*100)
print(t2)
运行结果:
[[4394029 7860119 5845909 ... 142463 2162240 515000]
[ 320053 185853 576597 ... 4231 41032 34727]
[ 5931 26679 39774 ... 148 1384 195]
[ 46245 0 170708 ... 279 4737 4722]]
****************************************************************************************************
[[4394029 320053 5931 46245]
[7860119 185853 26679 0]
[5845909 576597 39774 170708]
...
[ 142463 4231 148 279]
[2162240 41032 1384 4737]
[ 515000 34727 195 4722]]
numpy中的转置
常用数组转置:
- self.transpose();
- self.T;
- self.swapaxes(1.0):交换0和1轴。
numpy索引和切片
操作很简单,和python中列表的操作一样。
print(t2[2])
print("*"*100)
print(t2[2:])
print("*"*100)
print(t2[[2,8,10]])
print(t2[1,:])
print(t2[2:,:])
print(t2[2:,3])
print(t2[2:,:3])
print(t2[[2,8,10],:])
print(t2[:,0])
print(t2[:,2:])
print(t2[:,2::2])
print(t2[:,[0,2]])
a = t2[2,3]
print(a)
print(type(a))
b = t2[2:5,1:4]
print(b)
c = t2[[0,2,2],[0,1,3]]
print(c)
numpy中数值的修改
import numpy as np
a = np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10],[10,11,12,13]])
print(a)
print("*"*100)
a[:,1:3] = 0
print(a)
print("*"*100)
print(a==0)
a[a==0] = 1
print(a)
print("*"*100)
a = np.where(a>5,5,2)
print(a)
print("*"*100)
a = a.clip(3,4)
print(a)
运行结果:
[[ 1 2 3 4]
[ 4 5 6 7]
[ 7 8 9 10]
[10 11 12 13]]
****************************************************************************************************
[[ 1 0 0 4]
[ 4 0 0 7]
[ 7 0 0 10]
[10 0 0 13]]
****************************************************************************************************
[[False True True False]
[False True True False]
[False True True False]
[False True True False]]
[[ 1 1 1 4]
[ 4 1 1 7]
[ 7 1 1 10]
[10 1 1 13]]
****************************************************************************************************
[[2 2 2 2]
[2 2 2 5]
[5 2 2 5]
[5 2 2 5]]
****************************************************************************************************
[[3 3 3 3]
[3 3 3 4]
[4 3 3 4]
[4 3 3 4]]
numpy中的nan和inf
nan(NAN,Nan):not a number表示不是一个数字。
当我们读取本地的文件为float的时候,如果有缺失,就会出现nan 。当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大),就会出现nan。
nf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷
比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)
nan和inf的type类型都是float型
numpy中的nan的注意点:
- 两个nan是不相等的;
- np.count_nonzero(t!=t),可以统计t中nan的个数,因为t!=t返回bool值,利用布尔索引实现。
- np.isnan(t)与t!=t同;
- nan和任何值计算都是nan
在一组数据中单纯的把nan替换为0,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行
numpy中常用统计函数
- 求和:t.sum(axis=None)
- 均值:t.mean(a,axis=None)
- 受离群点的影响较大
- 中值:np.median(t,axis=None)
- 最大值:t.max(axis=None)
- 最小值:t.min(axis=None)
- 极差:np.ptp(t,axis=None) 即最大值和最小值只差
- 标准差:t.std(axis=None)
标准差是一组数据平均值分散程度的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值 反映出数据的波动稳定情况,越大表示波动越大,越不稳定。
用数组每列除nan外所有值的平均值代替nan:
import numpy as np
def fill_ndarray(t1):
for i in range(t1.shape[1]):
temp_col = t1[:,i]
nan_num = np.count_nonzero(temp_col!=temp_col)
if nan_num !=0:
temp_not_nan_col = temp_col[temp_col==temp_col]
temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean()
return t1
if __name__ == '__main__':
t1 = np.arange(24).reshape((4, 6)).astype("float")
t1[1, 2:] = np.nan
print(t1)
print("*"*100)
t1 = fill_ndarray(t1)
print(t1)
运行结果:
[[ 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.]]
结合matplotlib把数据呈现出来
1.英国和美国各自youtube1000的数据结合之前的matplotlib绘制出各自的评论数量的直方图
import numpy as np
from matplotlib import pyplot as plt
us_file_path = "./youtube_video_data/US_video_data_numbers.csv"
uk_file_path = "./youtube_video_data/GB_video_data_numbers.csv"
t_us = np.loadtxt(us_file_path,delimiter=",",dtype="int")
t_us_comments = t_us[:,-1]
t_us_comments = t_us_comments[t_us_comments<=5000]
print(t_us_comments.max(),t_us_comments.min())
d = 50
bin_nums = (t_us_comments.max()-t_us_comments.min())//d
plt.figure(figsize=(20,8),dpi=80)
plt.hist(t_us_comments,bin_nums)
plt.show()
运行结果: 4995 0
2.希望了解英国的youtube中视频的评论数和喜欢数的关系,应该如何绘制改图
import numpy as np
from matplotlib import pyplot as plt
us_file_path = "./youtube_video_data/US_video_data_numbers.csv"
uk_file_path = "./youtube_video_data/GB_video_data_numbers.csv"
t_uk = np.loadtxt(uk_file_path,delimiter=",",dtype="int")
t_uk = t_uk[t_uk[:,1]<=500000]
t_uk_comment = t_uk[:,-1]
t_uk_like = t_uk[:,1]
plt.figure(figsize=(20,8),dpi=80)
plt.scatter(t_uk_like,t_uk_comment)
plt.show()
运行结果:
|