numpy
1. numpy基础
(1). numpy创建数组(矩阵)
import numpy as np
a=np.array([1,2,3,4,5])
b=np.array(range(1,6))
c=np.arange(1,6)
np.arange的用法:arange([start,] stop[,step,],dtype=None)
#数组的类名
a=np.array([1,2,3,4,5])
print(type(a))
运行结果:
numpy.ndarray
#数组的类型
print(a.dtype)
运行结果:
dtype('int64')
#指定创建的数组的数据类型
a=np.array([1,0,1,0],dtype=np.bool) #或者使用dtype='?'
print(a)
运行结果:
array[True,False,True,False]
#修改数组的数据类型
print(a.astype('i1')) #或者使用a.astype(np.int8)
运行结果:
[1,0,1,0],dtype=int8
#修改浮点型的小数位
b=np.array([random.random() for i in range(10)]) #生成10个0到1的小数
print(b)
print(np.round(b,2)) #中的数字保留两位小数
运行结果:
[0.07859284 0.63999421 0.87230539 0.20005099 0.99937676 0.04664788
0.11377768 0.05528047 0.88686356 0.7185658 ]
[0.08 0.64 0.87 0.2 1. 0.05 0.11 0.06 0.89 0.72]
0.012
#数组的形状
a=np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])
print(a)
运行结果:
[[3 4 5 6 7 8]
[4 5 6 7 8 9]]
#查看数组的形状
print(a.shape)
运行结果:
(2,6) #第一个数字是行数,第二个数字是列数
#如果三个数的话第一个数字就是有几个矩阵
#修改数组的形状
print(a.reshape(3,4))
运行结果;
[[3 4 5 6]
[7 8 4 5]
[6 7 8 9]]
#数组的形状
a=np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])
a.flatten() #直接将多维数组变为一维数组
运行结果:
[3 4 5 6 7 8 4 5 6 7 8 9]
#加减乘除
print(a+1)
print(a-1)
print(a*2)
print(a/2)
运行结果:
[[2 3 4 5 6 7]
[3 4 5 6 7 8]]
[[ 6 8 10 12 14 16]
[ 8 10 12 14 16 18]]
[[1.5 2. 2.5 3. 3.5 4. ]
[2. 2.5 3. 3.5 4. 4.5]]
数组间的加减乘除
a=np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])
b=np.array([[21,22,23,24,25,26],[27,28,29,30,31,32]])
c=np.array(range(18))
c=c.reshape(3,6)
print(c)
d=np.array(range(2))
d=d.reshape(2,1)
print(a+b)
print(a*b)
print(a+c) #会报错 因为没有任何一个维度是相同的
print(a+d)
print(a*d) #只要是有一个维度相同就可以相加或者相减
运行结果:
[[24 26 28 30 32 34]
[31 33 35 37 39 41]]
[[ 63 88 115 144 175 208]
[108 140 174 210 248 288]]
[[ 3 4 5 6 7 8]
[ 5 6 7 8 9 10]]
[[0 0 0 0 0 0]
[4 5 6 7 8 9]]
(2). 轴(axis)
- 二维数组的轴
- 三维数组的轴
(3). numpy(读取数据)
np.loadtxt(frame,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
参数 | 解释 |
---|---|
frame | 文件、字符串或生产器,可以是.gz或ba2压缩文件 |
dtpye | 数据类型,可选,CSV的字符串以什么数据类型读入数组中,默认 np.float |
delimiter | 分隔字符串,默认是任何空格,改为逗号 |
skiprows | 跳过前X行,一般跳过第一行表头 |
usecols | 读取指定列,索引,元组类型 |
unpack | 如果True,读入属性将分别写入不同数组变量,False读入数据只写一个数组变量,默认False |
(4). numpy读取和存储数据
- 问题
现在这里有一个英国和美国各自youtube1000多个视频的点击,喜欢,不喜欢,评论数量([“views”,“likes”,“dislikes”,“comment_total”])的csv,运用刚刚所学习的只是,我们尝试来对其进行操作
(5). numpy中的转置
- 转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的也是为了更方便的去处理数据
转置的三种方法
import numpy as np
t=np.array(range(24))
t=t.reshape(4,6)
print(t.T)
print(t.transpose())
print(t.swapaxes)
运行结果:
[[ 0 6 12 18]
[ 1 7 13 19]
[ 2 8 14 20]
[ 3 9 15 21]
[ 4 10 16 22]
[ 5 11 17 23]]
(6). numpy索引和切片
import numpy as np
t=np.array(range(24))
t=t.reshape(4,6)
print(t)
print(t[1]) #取一行
print(t[1:3]) #取多行
print(t[:,2]) #取一列
print(t[:,2: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]]
[ 6 7 8 9 10 11]
[[ 6 7 8 9 10 11]
[12 13 14 15 16 17]]
[ 2 8 14 20]
[[ 2 3]
[ 8 9]
[14 15]
[20 21]]
(7). numpy中数值的修改
import numpy as np
t=np.array(range(24))
t=t.reshape(4,6)
t[:,2:4]=0
print(t)
运行结果:
[[ 0 1 0 0 4 5]
[ 6 7 0 0 10 11]
[12 13 0 0 16 17]
[18 19 0 0 22 23]]
(8). numpy中布尔索引
import numpy as np
t=np.array(range(24))
t=t.reshape(4,6)
print(t)
print(t<10)
t[t<10]=0 #把小于10的赋为0
print(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]]
[[ 0 0 0 0 0 0]
[ 0 0 0 0 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
(9). numpy中三元运算符
import numpy as np
t=np.arange(24).reshape(4,6)
print(t)
t=np.where(t<10,0,10)
#np.where 矩阵中小于10的变成0,大于10的变成10
print(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]]
(10). numpy中的clip(裁剪)
import numpy as np
t=np.arange(24).reshape(4,6)
print(t)
t=t.astype(float)
t[3,3:6]=np.nan #将第四排的第四列到第六列,变成nan,注意字符格式
print(t.clip(10,18)) #小于10的替换为10,大于18的替换为了18
运行结果:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
[[10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 11.]
[12. 13. 14. 15. 16. 17.]
[18. 18. 18. nan nan nan]]
(11). numpy中的nan和inf
- 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)
numpy中的nan的注意点:
- 两个nan不相等
IN:np.nan==np.nan
OUT:False
IN:np.nan!=np.nan
OUT:True - 利用上述的t矩阵,判断数组中nan的个数
IN:np.count_nonzero(t != t)
out:3 - 用np.isnan(t)来判断数字是否为nan,返回bool值类型,比如希望把nan替换为0
IN:t[np.isnan(t)]=0
OUT:print(t) - nan和任何值计算结果都是nan
- 那么问题来了,在一组数据中单纯的把nan替换为0,合适么?会带来什么样的影响?
比如,全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行
结局方法
#coding=utf-8
import numpy as np
def fill_ndarray(t1):
for i in range(t1.shape[1]): #shape0是行数 shape1是列数
temp_col=t1[:,i] #当前的一列有没有nan
nan_num = np.count_nonzero(temp_col!=temp_col) #count_nonzero不是0的数有多少个
if nan_num !=0: #不为0说明当前这一列中有nan
temp_not_nan_col=temp_col[temp_col==temp_col] #当前一列部位nan的array ,将等于的就赋值一下
temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean() #选中当前为nan的位置,把值 赋值为不为nan的均值
return t1
if __name__=='__main__':
t1=np.arange(24).reshape(4,6).astype('float')
t1[3,3:6]=np.nan
print(t1)
t1=fill_ndarry(t1)
print(t1)
运行结果:
[[ 0. 1. 2. 3. 4. 5.]
[ 6. 7. 8. 9. 10. 11.]
[12. 13. 14. 15. 16. 17.]
[18. 19. 20. nan nan nan]]
[[ 0. 1. 2. 3. 4. 5.]
[ 6. 7. 8. 9. 10. 11.]
[12. 13. 14. 15. 16. 17.]
[18. 19. 20. 9. 10. 11.]]
(12). 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) (标准差是一组数据平均值分散程度的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值反映出数据的波动稳定情况,越大表示波动越大,约不稳定。)
默认返回多维数组的全部的统计结果,如果指定axis则返回一个当前轴上的结果
(13). 解决问题
#coding=utf-8
'''
1.英国和美国各自youtube1000的数据结合之前的matplotlib绘制出各自的评论数量的直方图
'''
import numpy as np
from matplotlib import pyplot as plt
us_file_path='./youtube_video/US_video_data_numbers.csv'
uk_file_path='./youtube_video/GB_video_data_numbers.csv'
# t1=np.loadtxt(us_file_path,delimiter=',',dtype='int',unpack=True)
t_us=np.loadtxt(us_file_path,delimiter=',',dtype='int')
#取评论的数据
t_us_comments=t_us[:,-1] #-1就是最后一列
#选择比5000小的数据
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()
运行结果:
#coding=utf-8
'''
2.希望了解英国的youtube中视频的评论数和喜欢数的关系,应该如何绘制改图
'''
import numpy as np
from matplotlib import pyplot as plt
us_file_path='./youtube_video/US_video_data_numbers.csv'
uk_file_path='./youtube_video/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_comment,t_uk_like) #散点图
plt.show()
运行结果:
(14). 数组的拼接
- 竖直拼接
np.vstack((t1,t2)) - 水平拼接
np.hstack((t1,t2))
拆分就是拼接的反方向,不要搞混
练习:
#coding=utf-8
'''
现在希望把之前案例中两个国家的数据方法一起来研究分析,同时保留国家的信息(每条数据的国家来源),应该怎么办
'''
import numpy as np
us_data='./youtube_video/US_video_data_numbers.csv'
uk_data='./youtube_video/GB_video_data_numbers.csv'
# 加载国家数据
us_data=np.loadtxt(us_data,delimiter=',',dtype='int')
uk_data=np.loadtxt(uk_data,delimiter=',',dtype='int')
#添加国家信息
#构造全为0的数据 np.zeros((行,列))
zeros_data=np.zeros((us_data.shape[0],1)).astype('int')
#构造全为1的数据 np.ones((行,列))
ones_data=np.ones((uk_data.shape[0],1)).astype('int')
#分别添加一列全为0,1的数据
us_data=np.hstack((us_data, zeros_data))
uk_data=np.hstack((uk_data, ones_data))
#拼接两块数据
fin_data=np.vstack((us_data, uk_data))
print(fin_data)
运行结果:
[[4394029 320053 5931 46245 0]
[7860119 185853 26679 0 0]
[5845909 576597 39774 170708 0]
...
[ 109222 4840 35 212 1]
[ 626223 22962 532 1559 1]
[ 99228 1699 23 135 1]]
(15). 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)
(16). numpy生成随机数
(17). numpy的注意点copy和view
- a=b 完全不复制,a和b相互影响
- a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的,
- a = b.copy(),复制,a和b互不影响