什么是numpy
一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算。
为什么要学习numpy
- 快速
- 方便
- 科学计算的基础库
国际惯例,以上都是我复制的,保住了我cv程序员的尊严。
numpy创建数组(矩阵)
创建数组
import numpy as np
a = np.array([1, 2, 3, 4, 5])
b = np.array(range(1, 6))
# 上面a, b, c内容相同,注意arange和range的区别
c = np.arange(1, 6)
np.arange的用法:arange([start,], stop[, step, ], drype = None)
数组的类名:
In [1]: import numpy as np
In [2]: a = np.array([1, 2, 3, 4, 5])
In [3]: type(a)
Out[3]: numpy.ndarray
数据的类型
In [4]: a.dtype
Out[4]: dtype('int64')
numpy中常见的更多数据类型
类型 | 类型代码 | 说明 |
---|---|---|
int8、uint8 | i1、u1 | 有符号和无符号的8位(1个字节)整型 |
int16、uint16 | i2、u2 | 有符号和无符号的8位(2个字节)整型 |
int32、uint32 | i4、u4 | 有符号和无符号的8位(4个字节)整型 |
int64、uint64 | i8、u8 | 有符号和无符号的8位(8个字节)整型 |
float16 | f2 | 半精度浮点数 |
float32 | f4或f | 标准的单精度浮点数。与C的float兼容 |
float64 | f8或d | 标准的双精度浮点数。与C的double和Python的float对象兼容 |
float128 | f16或g | 扩展精度浮点数 |
complex64、complex128、complex256 | c8、c16、c32 | 分别用两个32为、64位或128位浮点表示的复数 |
bool | ? | 存储True和False值的布尔类型 |
数据类型的操作
创建指定的数据类型:
In [5]: a = np.array([1, 0, 1, 0], dtype = np.bool) # 或者使用dtype='?'
In [6]: a
Out[6]: array([ True, False, True, False], dtype=bool)
修改数组的数据类型:
In [7]: a.astype("i1") # 或者使用a.astype(np.int8)
Out[7]: array([1, 0, 1, 0], dtype=int8)
修改浮点型的小数位数
In [9]: b = np.array([random.random() for i in range(10)])
In [10]: b
Out[10]:
array([ 0.0485436 , 0.26320629, 0.69646413, 0.71811003, 0.3576838 ,
0.58919477, 0.84757749, 0.52428633, 0.486302 , 0.48908838])
In [11]: np.round(b, 2)
Out[11]: array([ 0.05, 0.26, 0.7 , 0.72, 0.36, 0.59, 0.85, 0.52, 0.49, 0.49])
那么问题来了,Python中如何保留固定位数的小数?
round(random.random, 3) # 第二个参数是保留小数的位数
数组的形状
In [12]: a = np.array([[3, 4, 5, 6, 7, 8], [4, 5, 6, 7, 8, 9]])
In [13]: a
Out[13]:
array([[3, 4, 5, 6, 7, 8],
[4, 5, 6, 7, 8, 9]])
查看数组的形状:
In [14]: a.shape
Out[14]: (2, 6)
修改数组的形状:
In [15]: a.reshape(3, 4)
Out[15]:
array([[3, 4, 5, 6],
[7, 8, 4, 5],
[6, 7, 8, 9]])
In [16]: a.shape
Out[16]: (2, 6) # 为什么a还是2行6列的数组呢?
In [17]: b = a.reshape(3, 4)
In [18]: b.shape
Out[18]: (3, 4)
In [19]: b
Out[19]:
array([[3, 4, 5, 6],
[7, 8, 4, 5],
[6, 7, 8, 9]])
在ipython下,调用了reshape之后立刻输出了结果,说明reshape是有返回值的,一般情况下这种有返回值的方法不会修改源数据。
把数组转化为1维度数据
In [20]: b.reshape(1, 12)
Out[20]: array([[3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 9]])
In [21]: b.flatten()
Out[21]: array([3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 9])
那有些小伙伴就非常的机智,我们给他reshape成1行12列的数组不就得了吗…仔细看一下,那是一维数组吗? flatten()方法,可以把数组转化为一维数组。
数组和数的计算
In [22]: a
Out[22]:
array([[3, 4, 5, 6, 7, 8],
[4, 5, 6, 7, 8, 9]])
In [23]: a + 1
Out[23]:
array([[ 4, 5, 6, 7, 8, 9],
[ 5, 6, 7, 8, 9, 10]])
In [24]: a * 3
Out[24]:
array([[ 9, 12, 15, 18, 21, 24],
[12, 15, 18, 21, 24, 27]])
这是一个nupy的广播机制造成的,在运算过程中,加减乘除的值被广播到所有的元素上面
数组和数组的计算
In [28]: a
Out[28]:
array([[3, 4, 5, 6, 7, 8],
[4, 5, 6, 7, 8, 9]])
In [29]: b
Out[29]:
array([[21, 22, 23, 24, 25, 26],
[27, 28, 29, 30, 31, 32]])
In [30]: a + b
Out[30]:
array([[24, 26, 28, 30, 32, 34],
[31, 33, 35, 37, 39, 41]])
In [31]: a * b
Out[31]:
array([[ 63, 88, 115, 144, 175, 208],
[108, 140, 174, 210, 248, 288]])
# 不同维度的数组计算
In [32]: c = np.arange(1, 13).reshape(3, 4)
In [33]: c
Out[33]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
In [34]: a
Out[34]:
array([[3, 4, 5, 6, 7, 8],
[4, 5, 6, 7, 8, 9]])
In [35]: a * c
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-35-fc01a05f2628> in <module>()
----> 1 a * c
ValueError: operands could not be broadcast together with shapes (2,6) (3,4)
But!!!!
In [40]: a # 2行6列的数组
Out[40]:
array([[3, 4, 5, 6, 7, 8],
[4, 5, 6, 7, 8, 9]])
In [41]: c # 1行6列的数组
Out[41]: array([1, 2, 3, 4, 5, 6])
In [42]: a - c
Out[42]:
array([[2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3]])
In [43]: a * c
Out[43]:
array([[ 3, 8, 15, 24, 35, 48],
[ 4, 10, 18, 28, 40, 54]])
In [40]: a # 2行6列的数组
Out[40]:
array([[3, 4, 5, 6, 7, 8],
[4, 5, 6, 7, 8, 9]])
In [41]: c # 1行6列的数组
Out[41]: array([1, 2, 3, 4, 5, 6])
In [42]: a - c
Out[42]:
array([[2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3]])
In [43]: a * c
Out[43]:
array([[ 3, 8, 15, 24, 35, 48],
[ 4, 10, 18, 28, 40, 54]])
In [45]: a # 2行6列的数组
Out[45]:
array([[3, 4, 5, 6, 7, 8],
[4, 5, 6, 7, 8, 9]])
In [46]: c # 2行1列的数组
Out[46]:
array([[1],
[2]])
In [47]: c + a # 相加
Out[47]:
array([[ 4, 5, 6, 7, 8, 9],
[ 6, 7, 8, 9, 10, 11]])
In [48]: a * c # 相乘
Out[48]:
array([[ 3, 4, 5, 6, 7, 8],
[ 8, 10, 12, 14, 16, 18]])
In [49]: c * a # 相乘
Out[49]:
array([[ 3, 4, 5, 6, 7, 8],
[ 8, 10, 12, 14, 16, 18]])
Why??
广播原则
如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
怎么理解呢?
可以把维度指的是shape所对应的数字个数
那么问题来了:
shape为(3, 3, 3)的数组能够和(3, 2)的数组进行计算么? No
shape为(3, 3, 2)的数组能够和(3, 2)的数组进行计算么? Yes
有什么好处呢?
举个例子:每列的数据减去列的平均值的结果
轴(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, 2 * 5 一共10个数据。
二维数组的轴
明白了轴的概念之后,对于shape返回的结果和reshape的结果能够更加清楚
三维数组的轴
明白了轴的概念之后,对于shape返回的结果和reshape的结果能够更加清楚
numpy读取数据
CSV:Comma-Separated Value,逗号分隔值文件
显示:表格状态
源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录
由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据,不过读取数据库也是很方便的。
np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
参数 | 解释 |
---|---|
frame | 文件、字符串或产生器,可以是.gz或bz2压缩文件 |
dtype | 数据类型,可选,CSV的字符串以什么数据类型读入数组中, |
delimiter | 分隔字符串,默认是任何空格、改为 逗号 |
skiprows | 跳过前x行,一般跳过第一行表头 |
usecols | 读取指定的列,索引,元祖类型 |
unpack | 如果True,读入属性将分别写入不同数组变量,False读入数据只写入一个数组变量,默认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(t2)
print("*" * 100)
# 取行
print(t2[2])
# 取连续多行
print(t2[2:])
# 取不连续的多行
print(t2[[2, 8, 10]])
# 取列
print(t2[1,:])
print(t2[[2,10,3],:])
print(t2[:, 0])
# 连续的多列
print(t2[:,2:])
# 取不连续多列
print(t2[:, [0, 2]])
# 取多行和多列,取第3行,第4列的值
print(t2[2, 3])
# 取多个不相邻的点
c = t2[[0, 2, 2], [0, 1, 3]]
print(c)
注意其中添加delimiter和dtype以及unpack的效果
delimiter:指定边界符号是什么,不指定会导致每行数据为一个整体的字符串二报错
dtype:默认情况下对于较大的数据会将其变为科学计数法
那么unpack的效果呢?
unpack:
默认是False(0),默认情况下,有多少条数据,就会有多少行。
为True(1)的情况下,每一列的数据会组成一行,原始数据有多少列,加载出来的数据就会有多少行相当于转置的效果。
那么问题来了:什么是转置?(这个线性代数里学过)
转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的也是为了更方便的去处理数据。
In [51]: t = np.arange(0, 18).reshape(3, 6)
In [52]: t
Out[52]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
In [53]: t.transpose()
Out[53]:
array([[ 0, 6, 12],
[ 1, 7, 13],
[ 2, 8, 14],
[ 3, 9, 15],
[ 4, 10, 16],
[ 5, 11, 17]])
In [54]: t.swapaxes(1, 0)
Out[54]:
array([[ 0, 6, 12],
[ 1, 7, 13],
[ 2, 8, 14],
[ 3, 9, 15],
[ 4, 10, 16],
[ 5, 11, 17]])
In [55]: t.T
Out[55]:
array([[ 0, 6, 12],
[ 1, 7, 13],
[ 2, 8, 14],
[ 3, 9, 15],
[ 4, 10, 16],
[ 5, 11, 17]])
以上的三种方法都可以实现二维数组的转置的效果,大家能够看出来,转置和交换轴的效果一样
那么,结合之前所学的matplotlib把英国和美国的数据呈现出来?
看到这个问题,我们应该考虑什么?
- 我们想要反映出什么样的结果,解决什么问题?
- 选择什么样的呈现方式?
- 数据还需要做什么样的处理?
- 写代码
numpy索引和切片
对于刚刚加载出来的数据,我如果只想选择其中的某一列(行)我们应该怎么做呢?
其实操作很简单,和python中列表的操作一样
In [57]: a = np.arange(0, 12).reshape(3, 4)
In [58]: a[1]
Out[58]: array([4, 5, 6, 7])
In [59]: a[:,2] # 取一列
Out[59]: array([ 2, 6, 10])
In [60]: a[1:3] # 取多行
Out[60]:
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [61]: a[:,2:4] # 取多列 ,前面放行 ,后面放列
Out[61]:
array([[ 2, 3],
[ 6, 7],
[10, 11]])
numpy中数值的修改
In [63]: t = np.arange(0, 24).reshape(4, 6)
In [64]: t
Out[64]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
In [65]: t[:, 2:4]
Out[65]:
array([[ 2, 3],
[ 8, 9],
[14, 15],
[20, 21]])
In [66]: t[:,2:4] = 0
In [67]: t
Out[67]:
array([[ 0, 1, 0, 0, 4, 5],
[ 6, 7, 0, 0, 10, 11],
[12, 13, 0, 0, 16, 17],
[18, 19, 0, 0, 22, 23]])
修改行列的值,我们能够很容易的实现,但是如果条件更复杂呢?
比如我们想要把t中小于10的数字替换为3
numpy中布尔索引
In [67]: t
Out[67]:
array([[ 0, 1, 0, 0, 4, 5],
[ 6, 7, 0, 0, 10, 11],
[12, 13, 0, 0, 16, 17],
[18, 19, 0, 0, 22, 23]])
In [68]: t < 10
Out[68]:
array([[ True, True, True, True, True, True],
[ True, True, True, True, False, False],
[False, False, True, True, False, False],
[False, False, True, True, False, False]], dtype=bool)
In [69]:
In [69]: t[t < 10] = 0
In [70]: t
Out[70]:
array([[ 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 10, 11],
[12, 13, 0, 0, 16, 17],
[18, 19, 0, 0, 22, 23]])
那么问题来了:
如果我们想把t中小于10的数字替换为0,把大于10的替换为10,应该怎么做??
numpy中三元运算符
In [71]: t = np.arange(24).reshape((4, 6))
In [72]: t
Out[72]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
In [73]: np.where(t < 10, 0, 10) # numpy的三元运算符
Out[73]:
array([[ 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 10, 10],
[10, 10, 10, 10, 10, 10],
[10, 10, 10, 10, 10, 10]])
那么问题又来了:
如果我们想把t中小于10的数字替换为0,把大于20的替换为20,应该怎么做??
numpy中的clip(裁剪)
In [92]: t
Out[92]:
array([[ 0., 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10., 11.],
[ 12., 13., 14., 15., 16., 17.],
[ 18., 19., 20., nan, nan, nan]])
In [93]: t.clip(10, 18)
Out[93]:
array([[ 10., 10., 10., 10., 10., 10.],
[ 10., 10., 10., 10., 10., 11.],
[ 12., 13., 14., 15., 16., 17.],
[ 18., 18., 18., nan, nan, nan]])
观察左边的操作:
小于10的替换为10,大于18的替换为了18,但是nan没有被替换,那么nan是什么?
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)
那么如何指定一个nan或者inf呢?
注意他们的type类型
In [94]: a = np.inf
In [95]: type(a)
Out[95]: float
In [96]: a = np.nan
In [97]: type(a)
Out[97]: float
numpy中的nan的注意点
# 两个nan是不相等的
In [98]: np.nan == np.nan
Out[98]: False
# np.nan != np.nan
In [99]: np.nan != np.nan
Out[99]: True
# 利用以上的特性,判断数组中的nan的个数
In [101]: t = np.array([1., 2., np.nan])
In [102]: t
Out[102]: array([ 1., 2., nan])
In [103]: np.count_nonzero(t != t)
Out[103]: 1
# 由于np.nan != np.nan,那么如何判断一个数字是否为nan呢?
# 通过np.isnan(a)来判断,返回bool类型,比如希望吧nan替换为0
In [104]: t
Out[104]: array([ 1., 2., nan])
In [105]: t[np.isnan(t)] = 0
# nan和任何值计算都为nan
In [106]: t
Out[106]: array([ 1., 2., 0.])
那么问题又双来了,在一组数据中单纯的把nan替换为0,合适么?会带来什么样的影响?
比如,全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行
那么又双叒问题来了:
如何计算一组数据的中值或者是均值
如何删除有缺失数据的那一行(列)[过两天在pandas中再介绍吧]
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则返回一个当前轴上的结果
标准差是一组数据平均值分散程度的一种度量。
一个较大的标准差,代表大部分数值和其平均值之间差异较大;
一个较小的标准差,代表这些数值较接近平均值。
反映出数据的波动稳定情况,越大表示波动越大,越不稳定。
import numpy as np
def fill_nadarray(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] # 当前一列不为nan的array
temp_not_nan_col.mean()
# 选中当前nan的位置,把值、赋值为不为nan的均值
temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean()
return t1
if __name__ == '__main__':
t1 = np.arange(12).reshape((3, 4)).astype("float")
t1[1, 2:] = np.nan
print(t1)
t1 = fill_nadarray(t1)
print(t1)
运行结果
[[ 0. 1. 2. 3.]
[ 4. 5. nan nan]
[ 8. 9. 10. 11.]]
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
ndarry缺失值填充均值
t中存在nan值,如何操作把其中的nan填充为每一列的均值
import numpy as np
def fill_nadarray(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] # 当前一列不为nan的array
temp_not_nan_col.mean()
# 选中当前nan的位置,把值、赋值为不为nan的均值
temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean()
return t1
if __name__ == '__main__':
t1 = np.arange(12).reshape((3, 4)).astype("float")
t1[1, 2:] = np.nan
print(t1)
t1 = fill_nadarray(t1)
print(t1)
麻烦吗?其实……在pandas中我们有更简单的方法处理缺失值,别着急,早进城晚进城,早晚都进城
小结
- 如何选择一行或者多行的数据(列)?
- 如何给选取的行或者列赋值?
- 如何大于把大于10的值替换为10?
- np.where如何使用?
- np.clip如何使用?
- 如何转置(交换轴)?
- 读取和保存数据为csv
- np.nan和np.inf是什么
- 常用的统计函数你记得几个?
- 标准差反映出数据的什么信息
动手
英国和美国各自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]
# 选择比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.savefig("./t1.png")
希望了解英国的youtube中视频的评论数和喜欢数的关系,应该如何绘制改图
import numpy as np
us_data = "./youtube_video_data/US_video_data_numbers.csv"
uk_data = "./youtube_video_data/GB_video_data_numbers.csv"
# 加载国家数据
us_data = np.loadtxt(us_data, delimiter=",", dtype="int")
uk_data = np.loadtxt(uk_data, delimiter=",", dtype="int")
# 添加国家信息
# 构造全为0的数据
zeros_data = np.zeros((us_data.shape[0], 1)).astype(int)
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))
# 拼接两组数据
final_data = np.vstack((us_data, uk_data))
print(final_data)
数组的拼接
现在我希望把之前案例中两个国家的数据方法一起来研究分析,那么应该怎么做?
In [111]: t1
Out[111]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
In [112]: t2
Out[112]:
array([[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
In [113]: np.vstack((t1, t2)) # 竖直拼接(vertically)
Out[113]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
In [114]: np.hstack((t1, t2)) # 水平拼接(horizontally)
Out[114]:
array([[ 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17],
[ 6, 7, 8, 9, 10, 11, 18, 19, 20, 21, 22, 23]])
数组的行列交换
数组水平或者竖直拼接很简单,但是拼接之前应该注意什么?
竖直拼接的时候:每一列代表的意义相同!!!否则牛头不对马嘴(还是驴唇不对马嘴来着?)
如果每一列的意义不同,这个时候应该交换某一组的数的列,让其和另外一类相同
那么问题来了?
如何交换某个数组的行或者列呢?
In [115]: t = np.arange(12, 24).reshape(3, 4)
In [116]: t
Out[116]:
array([[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
In [118]: t[[1, 2], :] = t[[2, 1], :] # 行交换
In [119]: t
Out[119]:
array([[12, 13, 14, 15],
[20, 21, 22, 23],
[16, 17, 18, 19]])
In [120]: t[:, [0, 2]] = t[:, [2, 0]] # 列交换
In [121]: t
Out[121]:
array([[14, 13, 12, 15],
[22, 21, 20, 23],
[18, 17, 16, 19]])
现在希望把之前案例中两个国家的数据方法一起来研究分析,同时保留国家的信息(每条数据的国家来源),应该怎么办?
import numpy as np
us_data = "./youtube_video_data/US_video_data_numbers.csv"
uk_data = "./youtube_video_data/GB_video_data_numbers.csv"
# 加载国家数据
us_data = np.loadtxt(us_data, delimiter=",", dtype="int")
uk_data = np.loadtxt(uk_data, delimiter=",", dtype="int")
# 添加国家信息
# 构造全为0的数据
zeros_data = np.zeros((us_data.shape[0], 1)).astype(int)
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))
# 拼接两组数据
final_data = np.vstack((us_data, uk_data))
print(final_data)
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生成随机数
参数 | 解释 |
---|---|
.rand(d0, d1, ..dn) | 创建d0-dn维度的均匀分布的随机数数组,浮点数,范围从0·1 |
.rand(d0, d1, ..dn) | 创建d0-dn维度的标准正态分布随机数,浮点数,平均数0,标准差1 |
.randint(low, high, (shape)) | 从给定上下限范围选取随机数整数,范围是low, high, 形状是shape |
.uniform(low, high, (size)) | 产生具有均匀分布的数组,low起始值,high结束值,size形状 |
.normal(loc, scale, (size)) | 从指定正态分布中随机抽取样本,分布中心是loc(概率分布的均值),标准差是scale,形状是size |
.seed(s) | 随机数种子,s是给定的种子值。因为计算机生成的是伪随机数,所以通过设定相同的随机数种子,可以每次生成相同的的随机数 |
import numpy as np
np.random.seed(10)
t = np.random.randint(0, 20, (3, 4))
print(t)
# 运行结果
[[ 9 4 15 0]
[17 16 17 8]
[ 9 0 10 8]]
分布的补充
1.均匀分布
在相同的大小范围内的出现概率是等可能的
\2. 正态分布
呈钟型,两头低,中间高,左右对
numpy的注意点copy和view
- a=b 完全不复制,a和b相互影响
- a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的。
- a = b.copy(),复制,a和b互不影响
“人间处处是繁华,你要全力以赴开花”
Macsen Chu