numpy入门

参考w3cschool numpy tutorial(基本上就是照着翻译,然后加入自己的理解,顺便把代码结果附上,over)

数组

可以将list tuple直接通过array()转化成ndarray

import numpy as np  
arr = np.array([1, 2, 3, 4, 5])  // arr = np.array((1, 2, 3, 4, 5))  
printf(arr)  
printf(type(arr))  

numpy的数组存在维度,当然python可以通过list嵌套实现,但是并不是真正意义上的数组,肯定没有这个快,而且没有现成的方法

可以通过x.ndim方法来检查数组的维度

前面提到可以通过np.array()来转化一个数组,后面可以跟一个参数ndim来显示的指定维度(不显示地指定ndim的参数的话,会根据传入的list..的维度来决定数组的维度)

arr = np.array([1, 2, 3, 4], ndmin=5)  
print(arr)  
res: [[[[[1 2 3 4]]]]]  

既然都是数组了,那肯定支持下标索引,但是这里的索引有所差异,一般我们的索引都是这样的arr[3][2][1]这样的,但是在numpy里面,需要arr[3,2,1]这样访问。

arr = np.array([[1, 2, 3], [4, 5, 6]])  
print(arr[1, 2])  
res: 6  

同样支持负数索引

arr = np.array([[1, 2, 3], [4, 5, 6]])  
print(arr[1, -1])  
res: 6  

同样支持索引,这里表示得到arr下标为1的位置的元素,并拿其从0到1(左闭右开)的元素,形成一个数组

arr = np.array([[1, 2, 3], [4, 5, 6]])  
print(arr[1, 0:1])  
res: [4]  

后面同样可以跟步长

arr = np.array([1, 2, 3, 4, 5, 6, 7])  
print(arr[::2])  
res: [1 3 5 7]  
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])  
print(arr[1, 1:4])  
res: [7, 8, 9]  

####数据类型
#####python的数据类型:字符串,整数,浮点数,布尔数,复数

#####numpy的数据类型:

i - integer  
b - boolean  
u - unsigned integer 无符号整型  
f - float  
c - complex float 复数浮点数  
m - timedelta   
M - datetime 日期时间  
O - object 对象  
S - string  
U - unicode string 采用unicode编码的字符串   
V - fixed chunk of memory for other type ( void ) void  

可以在np.array()里面显示的调用类型声明,如果声明有误,比如是字符串,后面跟了一个dtype=’i’,就会报错

i,u,f,S 可以定义大小

arr = np.array([1, 2, 3, 4], dtype='i4')  #四个字节 一个字节八位  
print(arr)  
print(arr.dtype)  
res: [1 2 3 4]  
int32  

#####数组类型转化
通过数组的astype(‘类型’)方法来进行copy

arr = np.array([1.1, 2.1, 3.1])  
newarr = arr.astype('i')  
newarr[0] = 10  
print(newarr)  
print(arr)  
res: [10  2  3]  
    [1.1 2.1 3.1]  

里面的参数可以写完整一点:int、bool 这样都是可识别的

#####视图和拷贝的区别
类似浅拷贝和深拷贝的关系
view:视图,也就是浅拷贝,修改这个值,会连带修改它的原主人,同样,修改原主人也会影响view,连坐

arr = np.array([1, 2, 3, 4, 5])  
x = arr.view()  
arr[0] = 42  
print(arr)  
print(x)  
res: [42  2  3  4  5]  
     [42  2  3  4  5]  
arr = np.array([1, 2, 3, 4, 5])  
x = arr.view()  
x[0] = 31  
print(arr)  
print(x)  
res: [31  2  3  4  5]  
     [31  2  3  4  5]  

copy: 拷贝,深拷贝,独立的一份

tips:view有一个属性base:原数组,copy没有,修改base就是修改原数组,同样会引起view的改变

arr = np.array([1, 2, 3, 4, 5])  
x = arr.copy()  
y = arr.view()  
y[0] = 2  
print(x.base)  
print(y.base)  
print(type(y.base))  
print(y)  
y.base[0] = 0  
print(arr)  
print(y)  

####shape方法
前面提到 ndim方法(和ndim一样,后面没有括号,应该是属性,习惯说成方法),可以拿到数组的维度,这里的shape方法则会返回更加具体,会返回每个维度的在当前维度元素的个数(返回的是元组)

arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])  
print(type(arr.shape))  
print(arr.shape)  
res: <class 'tuple'>  
     (2, 4)  
arr = np.array([1, 2, 3, 4], ndmin=5)  
print(arr)  
print('shape of array :', arr.shape)  
res: [[[[[1 2 3 4]]]]]  
     shape of array : (1, 1, 1, 1, 4)  

####reshape方法
顾名思义就是改变维度,但是reshape需要维度对应,不能随意改变维度,比如一维有十二个元素,满足二维的3 * 4,那么就可以改变,但是不满足就不能改变,比如2 * 5

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])  
newarr = arr.reshape(4, 3)  
print(newarr)  
res:    
[[ 1  2  3]  
 [ 4  5  6]  
 [ 7  8  9]  
 [10 11 12]]  

而且reshape返回的是原数组的view,里面有base属性,修改会造成连坐
tips:可以使用unknown dimension,如果你有某一个维度不知道里面具体有多少元素,那么你可以在reshape里面写一个-1,numpy为为你自动计算(前提是可以算出来)

如果reshape里面的参数是-1,则会将数组展成一维数组

arr = np.array([[1, 2, 3], [4, 5, 6]])  
newarr = arr.reshape(-1)  
print(newarr)  
res:[1 2 3 4 5 6 7 8]  

####数组迭代
1、经典for循环,拿到的是最外层数组里面的元素(里面的n-1维数组),可以接着套娃,处理高维数据比较复杂

arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])  
for x in arr:  
  print(x)  
res:   
[[1 2 3]  
 [4 5 6]]  
[[ 7  8  9]  
 [10 11 12]]  

2、np.nditer(arr)迭代每一个元素

arr = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])  
for x in np.nditer(arr):  
  print(x)  
res:  

在这个迭代中,我们可以传一个op_dtypes的参数来修改数组中元素的值的类型,op->操作,dtypes->类型,但是呢,并不能直接在数组中操作,规定要再传一个参数,flags=[‘buffered’]表示在一个额外的空间buffer里进行操作,龟腚。

arr = np.array([1, 2, 3])  
for x in np.nditer(arr, flags=['buffered'], op_dtypes=['S']):  
  print(x)  
  print(type(x))  
res:   
b'1'  
<class 'numpy.ndarray'>  
b'2'  
<class 'numpy.ndarray'>  
b'3'  
<class 'numpy.ndarray'>  

tips:自python更新到3.0后,dtype类型中’S’被修改为 (byte-)string类型,所以输出含b指的是此字符串类型为byteString类,有点搞

然后,这个参数arr同样支持切片(包括步长)

arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])  
for x in np.nditer(arr[:, ::2]):  
  print(x)  
res:   

3、enumerate,python原来自带有一个enumerate,可以返回list、tuple和string的下标和对应元素,同样的,numpy里也有一个ndenumerate,使用方法类似enumerate

arr = np.array([1, 2, 3])  
for idx, x in np.ndenumerate(arr):  
  print(idx, x)  
res:  
(0,) 1  #这个如果不是idx,x,直接是x的话,拿到的是一个tuple  
(1,) 2  #这里的idx同样是一个tuple  
(2,) 3  
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])  
for idx, x in np.ndenumerate(arr):  
  print(idx, x)  
res:  #如果是高维的,同样是挨个遍历  
(0, 0) 1  
(0, 1) 2  
(0, 2) 3  
(0, 3) 4  
(1, 0) 5  
(1, 1) 6  
(1, 2) 7  
(1, 3) 8  

感觉别人有点盛气凌人,是我的错觉吗,一定要学会控制自己的情绪,一定要抱持冷静客观,喷人是解决不了问题的(可能会爽)QAQ 也许是最近压力太大造成的,好好休息吧