numpy基本使用

什么是numpy

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

为什么要学习numpy
  1. 快速
  2. 方便
  3. 科学计算的基础库

国际惯例,以上都是我复制的,保住了我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、uint8i1、u1有符号和无符号的8位(1个字节)整型
int16、uint16i2、u2有符号和无符号的8位(2个字节)整型
int32、uint32i4、u4有符号和无符号的8位(4个字节)整型
int64、uint64i8、u8有符号和无符号的8位(8个字节)整型
float16f2半精度浮点数
float32f4或f标准的单精度浮点数。与C的float兼容
float64f8或d标准的双精度浮点数。与C的double和Python的float对象兼容
float128f16或g扩展精度浮点数
complex64、complex128、complex256c8、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个数据。

二维数组的轴

img明白了轴的概念之后,对于shape返回的结果和reshape的结果能够更加清楚

三维数组的轴

img明白了轴的概念之后,对于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把英国和美国的数据呈现出来?

看到这个问题,我们应该考虑什么?

  1. 我们想要反映出什么样的结果,解决什么问题?
  2. 选择什么样的呈现方式?
  3. 数据还需要做什么样的处理?
  4. 写代码

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则返回一个当前轴上的结果

δ = 1 N ∑ i = 1 N ( x i − μ ) 2 δ = \sqrt{\frac{1}{N}\sum_{i=1}^N(x_i-μ)^2} δ=N1i=1N(xiμ)2

标准差是一组数据平均值分散程度的一种度量。
一个较大的标准差,代表大部分数值和其平均值之间差异较大;
一个较小的标准差,代表这些数值较接近平均值。
反映出数据的波动稳定情况,越大表示波动越大,越不稳定。

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中我们有更简单的方法处理缺失值,别着急,早进城晚进城,早晚都进城

小结

  1. 如何选择一行或者多行的数据(列)?
  2. 如何给选取的行或者列赋值?
  3. 如何大于把大于10的值替换为10?
  4. np.where如何使用?
  5. np.clip如何使用?
  6. 如何转置(交换轴)?
  7. 读取和保存数据为csv
  8. np.nan和np.inf是什么
  9. 常用的统计函数你记得几个?
  10. 标准差反映出数据的什么信息

动手

英国和美国各自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")

img

希望了解英国的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)

img

数组的拼接

现在我希望把之前案例中两个国家的数据方法一起来研究分析,那么应该怎么做?

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)

img

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. 正态分布
​ 呈钟型,两头低,中间高,左右对

img

numpy的注意点copy和view

  1. a=b 完全不复制,a和b相互影响
  2. a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的。
  3. a = b.copy(),复制,a和b互不影响

“人间处处是繁华,你要全力以赴开花”
2020-8-14 凌晨
Macsen Chu

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值