python数据分析:numpy库详解

文章目录

  • 一、numpy基本操作
    • 1.1数组的创建方式
    • 1.2 ndarray常用数据类型
  • 二、多维数组
    • 2.1基本计算
    • 2.2 数组索引和切片
    • 2.3 布尔索引
    • 2.4 值的替换
  • 三、numpy数组操作
    • 3.1numpy数组广播机制
    • 3.2数组的形状操作
    • 3.3不同数组的组合
    • 3.4 数组切割
    • 3.5数组的转置
  • 四、CSV文件操作
    • 4.1文件保存
    • 4.2文件读取
  • 五、NAN和INF
    • 5.1 NAN和INF定义
    • 5.2 NAN与INF缺失值处理


一、numpy基本操作

Numpy种的数组与Python种的列表区别:

  1. 一个列表可以存储多种数据类型。例如:a=[1,‘a’],而数组只能存储相同的数据类型。
  2. 数组可以使多维的,当多维数组中所有数据使数值类型时,相当于线代中的矩阵,是可以进行运算的。

1.1数组的创建方式

numpy中数组的数据类型叫做ndarray,以下是两种创建方式:
1、np.array():使用列表的形式创建数组

import numpy as np
a1=np.array([1,2,3,4])
print(a1)
print(type(a1))

输出结果:

[1 2 3 4]
<class 'numpy.ndarray'>

2、np.arange():
使用方法:类似于python中的range

a2=np.arange(2,21,2)
print(a2)
print(type(a2))

输出结果:

[ 2  4  6  8 10 12 14 16 18 20]
<class 'numpy.ndarray'>

3、使用np.random生成随机数组
(1)np.random.random((N,N)):生成N行N列的数组

a1=np.random.random((2,2))#生成两行两列数组
a1

输出结果:

array([[0.18400013, 0.7420395 ],
       [0.78453996, 0.82036748]])

(2)np.random.randint(M,N,size=(m,n)):生成m行n列,范围在[M,N)之间的整型数组。

a1=np.random.randint(0,10,size=(4,5))
a1

输出结果:

array([[9, 0, 9, 9, 6],
       [6, 7, 8, 4, 9],
       [8, 8, 3, 6, 3],
       [3, 6, 6, 4, 8]])

4、使用函数生成特殊数组

a1=np.zeros((2,2))#生成所有元素全为0的2行2列数组
a2=np.ones((2,3))#生成所有元素全为1的2行3列数组
a3=np.full((2,3),8)#生成所有元素全为8的2行3列数组
a4=np.eye(3)#生成一个在斜方形上权威1,其余元素均为0的3×3矩阵
print(a1)
print(a2)
print(a3)
print(a4)

输出结果:

[[0. 0.]
 [0. 0.]]
[[1. 1. 1.]
 [1. 1. 1.]]
[[8 8 8]
 [8 8 8]]
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

总结:

  1. 数组中的数据类型是一致的,不能同时出现多种类型
  2. 创建数组的四种方式:
    np.array
    np.arange
    np.random
    np特殊函数

1.2 ndarray常用数据类型

通过dtype可以看到数组中元素的数据类型(待填充)

数据类型 描述 唯一标识符
bool 用一个字节存储(True or False) ’b‘
int8 用一个字节大小 -128-127 ’i‘
int16 16位整数 ’i2‘
int32 32位整数 ’i4‘
int64 64位整数 ’i8‘
uint8 无符号数,0-255 ’u‘
uint16 无符号16位整数 ’u2‘
uint32 无符号32位整数 ’u4‘
uint64 无符号64位整数 ’u8‘
float16 半精度浮点数 16位 ’f2‘
float32 单精度浮点数 32位 ’f4‘
float64 双精度浮点数64位 ’f8‘
complex64 复数,两个32位浮点数 表示实部虚部 ’c8‘
complex128 复数,两个64位浮点数 表示实部虚部 ’c16‘
object_ python对象 ’O‘
string_ 字符串 ’S‘
unicode_ unicode类型 ’U‘

代码示例:
1、显示数据类型

a=np.arange(10)
print(a)
print(a.dtype)

输出结果:

[0 1 2 3 4 5 6 7 8 9]
int32

代码示例:

import numpy as np
b=np.array([1,2,3,4,5],dtype=np.int8)
print(b)
print(b.dtype)

输出结果:

[1 2 3 4 5]
int8

2、转化数据类型
代码示例:

f=np.array(['a','c'],dtype='S')
e=np.array(['a','c'],dtype='U')
uf=f.astype('U')
print(uf.dtype)

输出结果:

<U1

二、多维数组

2.1基本计算

1、计算维度:ndarray.ndim()
示例:

a1=np.array([1,2,3])
print(a1.ndim)
a2=np.array([[1,2,3],[4,5,6]])
print(a2.ndim)

输出结果:

1
2

2、计算行数和列数:ndarray.shape()
示例:

print(a1.shape)
print(a2.shape)

输出结果:

(3,)
(2, 3)

3、变化数组的行数和列数:ndarray.reshape()
4、将数组扁平化,转化为一维数组:ndarray.flatten()

a3=a2.flatten()
print(a3)

输出结果:

[1 2 3 4 5 6]

5、获取数组元素个数:ndarray.size()

a2=np.array([[1,2,3],[4,5,6]])
print(a2.size)

2.2 数组索引和切片

1、获取某行数据
(1)若为一维数组:获取某一个数值

#索引操作
a1=np.arange(0,24)
print(a1[1])
#切片操作
print(a1[4:6])

输出结果:

1
[4 5]

(2)若为多维数组:获取某一行数值

a2=np.arange(0,24).reshape(4,6)
print(a1[0:3])

输出结果:

[ 6  7  8  9 10 11]
[[ 6  7  8  9 10 11]
 [12 13 14 15 16 17]]

2、获取某几行数据

#1,获取连续的几行的数据
a1=np.arange(0, 24).reshape((4,6))
print(a1[0:2])#获取0行到1行的数据
#2.获取不连续的几行的数据
print(a1[[0,2,3]])
#3,也可以使用负数进行索引
print(a1[[-1,-2]])

输出结果:

[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]]
[[ 0  1  2  3  4  5]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
[[18 19 20 21 22 23]
 [12 13 14 15 16 17]]

3、可以获取某行某列数据

al=np.arange(0,24).reshape((4,6))
print(a1[1,1])#获取1行1列的数据
print(a1[0:2,0:2])#获取0-1行的0-1列的数据
print(a1[[1,2],[2,3]])#获取(1,2)和(2,3)的两个数据,这也叫花式索引

输出结果:

7
[[0 1]
 [6 7]]
[ 8 15]

4、获取某列数据

a1 = np.arange(0, 24).reshape((4,6)
print(al[:,1])#获取第1列的数据

2.3 布尔索引

布尔索引是矢量运算

a2=np.arange(24).reshape((4,6))
print(a2)
a2<10
a2[a2<10]

输出结果:

[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
 
array([[ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True, False, False],
       [False, False, False, False, False, False],
       [False, False, False, False, False, False]])

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

逻辑运算包括:>,<,<=,>=,&,|等

2.4 值的替换

1、利用索引实现

a1=np.arange(0, 24).reshape((4,6))
a1[3]=0#将第三行的所有值部替换成0
print(a1)

输出结果:

[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [ 0  0  0  0  0  0]]

2、利用条件索引实现

a1=np.arange(0, 24).reshape((4,6))
a1[a1<10]=0#将小于10的值替换为0
print(a1)

输出结果:

[[ 0  0  0  0  0  0]
 [ 0  0  0  0 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]

3、使用条件函数where实现

#where函数:
al=np.arange(0,24).reshape((4 ,6))
a2=np.where(al < 10,1,0)#把a1中所有小于10的数全部变成1,其余的变成0
print(a2)

三、numpy数组操作

3.1numpy数组广播机制

如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为他们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
案例分析:
(1)shape 为(3,8,2)的数组能和(8,3)的数组进行运算吗?
分析:不能,因为按照广播原则,从后面往前面数,(3,8,2)和(8,3)中的2和3不相等,所以不能进行运算。
(2)shape 为(3,8,2)的数组能和(8,1)的数组进行运算吗?
分析:能,因为按照广播原则,从后面往前面数,(3,8,2)和(8,1)中的2和1虽然不相等,但是因为有一方的长度为1,所以能参与运算。
(3)shape 为(3,1,8)的数组能和(8,1)的数组进行运算吗?
分析:能,因为按照广播原则,从后面往前面数,(3,1,4)和(8,1)中的4和1虽然不相等且1和8不相等,但是因为这两项中有一方的长度为1,所以能参与运算。

1、数组与数的计算
在Python列表中,想要对列表中所有的元素都加一个数,要么采用 map函数,要么循环整个列表进行操作。但是Numpy中的数组可以直接在数组上进行操作。示例代码如下:

import numpy as np
al=np.random .random((3,4))
print(a1)
#如果想要在a1数组上所有元素都乘以10,那么可以通过以下来实现
a2=a1*10
print(a2)
#也可以使用round让所有的元素只保留2位小数a3=a2.round(2)

2、数组与数组之间计算
(1)结构相同的数组

a1=np.arange(0, 24).reshape((3,8))
a2=np.random.randint(1,10,size=(3,8))
a3=al + a2#相减/相除/相乘都是可以的
print(a1)
print(a2)
print(a3)

(2)行数相同且只有一列的数组

a1=np.random.randint(10, 20,size(3,80))#3行8列
a2=np.random.randint(1,10,size=(3,1))#3行1列
a3=a1 - a2#行数相同,且a2只有1列,能互相运算
print(a3)

3.2数组的形状操作

1、reshape和resize
(1)reshape:reshape是将数组转换成指定的形状,然后返回转换后的结果,对于原数组的形状是不公发生改变的。调用方式:

a1=np.random.randint(0, 10, size=(3,4))
a2=al.reshape((2,6))#将修改后的结果返回,不会影响原数组本身

(2)resize:2resize是将数组转换成指定的形状,会直接修改数组本身。并不会返回任何值。调用方式:

a1=np.random.randint(0,10, size=(3,4))
al.resize((2,6)) #a1本身发生了改变

2、flatten和ravel
两个方法都是将多维数组转换为一维数组,但是有以下不同:
(1)flatten是将数组转换为一维数组后,然后将这个拷贝返回回去,所以后续对这个返回值进行修改不影响之前的数组。
(2)rave1是将数组转换为一维数组后,将这个视图(可以理解为引用)返回回去,所以后续对这个返回值进行修改影响之前的数组。
比如以下代码:

x=np.array([[1,2],[3,3]])
x.flatten()[1]=10#此时的x[1]的位置元素还是1
print(x)
x.ravel()[1] = 10#此时x[1]元素是10
print(x)

3.3不同数组的组合

1、vstack:将数组按垂直方向进行叠加,数组的列数必须相同。

a1=np.random.randint(0,10,size=(3,5))
a2=np.random.randint(0,10,size=(2,5))
a3=np.vstack([a1,a2])

2、hstack:将数组按水平方向进行叠加,数组的行数必须相同。

a1=np.random.randint(0,10,size=(3,5))
a2=np.random.randint(0,10,size=(3,4))
a3=np.hstack([a1,a2])

3、concatenate([], axis):将两个数组进行叠加,但是具体是按水平方向还是按垂直方向。则要看axis的参数,**如果 axis=0,那么代表的是往垂直方向(行〉叠加,如果 axis=1,那么代表的是往水平方向(列)上叠加,**如果 axis=None ,那么会将两个数组组合成一个一维数组。需要注意的是,如果往水平方向上叠加,那么行必须相同,如果是往垂直方向叠加,那么列必须相同。示例代码如下:

a1=np.random.randint(0,10,size=(3,5))
a2=np.random.randint(0,10,size=(2,5))
a3=np.concatenate([a1,a2],axis=0)
print(a3)

3.4 数组切割

通过hsplit和vsplit以及array_split可以将一个数组进行切割
1、hsplit: hsplit :按照水平方向进行切割。用于指定分割成几列,可以使用数字来代表分成几部分,也可以使用数组来代表分割的地方。示例代码如下:

hs1=np.random.randint(0,10,size=(3,4))
print(hs1)
print(np.hsplit(hs1,2))
print(np.hsplit(hs1,(1,2)))

输出结果:

[[2 1 8 6]
 [3 2 8 5]
 [7 3 6 9]]
[array([[2, 1],
       [3, 2],
       [7, 3]]), array([[8, 6],
       [8, 5],
       [6, 9]])]

[array([[3],
        [8],
        [9]]),
 array([[4],
        [7],
        [3]]),
 array([[3, 7],
        [7, 2],
        [7, 1]])]

2、vsplit: vsplit :按照垂直方向进行切割。用于指定分割成几行,可以使用数字来代表分成几部分,也可以使用数组来代表分割的地方。格式与hsplit相同
3、 split/ array_split)( arway , indicate_or_seciont ,axis),用于指定切割方式,在切割的时候需要指定是按照行还是按照列,axis=1代表按照列,axis=0 代表按照行。

3.5数组的转置

numpy中的数组其实就是线性代数中的矩阵。矩阵是可以进行转置的。ndarray有一个T属性,可以返回这个数组的转置的结果。示例代码如下:

a1=np.arange(0,10,size=(4,6))
a2=a1.T
print(T)

除此之外,还有一个transpose,此函数会修改返回值,影响原来的数组

a1=np.arange(0,10,size=(4,6))
a2=a1.transpose()

四、CSV文件操作

4.1文件保存

有时候我们有了一个数组,需要保存到文件中,那么可以使用np.savetxt来实现。相关的函数描述如下:

np.savetxt(frame ,array,fmt=%.18e ' , delimiter=None)
frame:文件、字符串或产生器,可以是,gz或.bz2的压缩文件
array :存入文件的数组
fmt:写入文件的格式,例如:%d 3.2f %.18e
delimiter:分割字符串,默认是任何空格

代码示例:

import numpy as np
a=np.random.randint(0,10,size=(3,6))
np.savetxt("a.csv",a,fmt="%d",delimiter=',')

在当前目录下会出现:
在这里插入图片描述
python数据分析:numpy库详解_第1张图片
若想要加上列名称则调用函数格式为:

np.savetxt("a.csv",a,fmt="%d",delimiter=',',header="英语,数学,语文,物理,化学,生物",comment="")

4.2文件读取

有时候我们的数据是需要从文件中读取出来的,那么可以使用np.loadtxt来实现。相关的函数描述如下:

np.loadtxt(frame,dtype=np .float,delimiter=None,unpack=False)
frame:文件、字符串永产生器,可以是-gz或.bz2的压缩文件。
dtype:数据类型,可选。
delimiter:分割字符串,默认是任何空格。
skiprows :跳过前面×行。
usecols :读取指定的列,用元组组合。
unpack :如果True,读取出来的数组是转置后的。

代码示例:

b=np.loadtxt("a.csv",dtype=int,delimiter=',')
print(b)

五、NAN和INF

5.1 NAN和INF定义

首先我们要知道这两个英文单词代表的什么意思:

  1. NAN :Not A number,不是一个数字的意思,但是他是属于浮点类型的,所以想要进行数据操作的时候需要注意他的类型。
  2. INF :Infinity ,代表的是无穷大的意思,也是属于浮点类型。np.inf 表示正无穷大,-np.inf表示负无穷大,一般在出现除数为0的时候为无穷大。比如 2/0 .

NAN代码示例:

a=np.random.randint(0,10,size=(3,5))
a=a.astype(np.float)
a[1,2]=np.NAN
print(a)

输出结果:

[[ 0.  4.  6.  2.  0.]
 [ 5.  8. nan  8.  2.]
 [ 8.  1.  7.  4.  4.]]

INF代码示例:

print(a/0)

输出结果:

[[inf inf inf inf inf]
 [inf inf nan inf inf]
 [inf nan inf inf inf]]

5.2 NAN与INF缺失值处理

(1)删除缺失值,并将数组转化为一维数组

#1,删除所有NAN的值,因为删除了值后数组将不知道该怎么变化,所以会被变成一维数组
data=np.random.randint(0,10,size=(3,5)).astype(np.float)
data[0,1]=np.nan
print(data)
data=data[~np.isnan(data)] #此时的data会没有nan,并且变成一个1维数组
print(data)

(2)删除缺失值所在行

#2.删除NAN所在的行
data=np.random.randint(0 , 10,size=(3,5)).astype(np.float)
#将第(0,1)和(1,2)两个值设器为NAN
data[[0,1],[1,2]]=np.NAN
print(data)
#获取哪些行有NAN
lines=np.where(np.isnan(data))[0]
#使用delete方法删除指定的行, axis=0表示删除行,lines表示删除的行号
datal=np.delete(data,lines, axis=0)
print(datal)

(3)缺失值替换

b=np.loadtxt("b.csv",skiprows=1,encoding='ISO-8859-1',dtype=np.str)
b[b=='']=np.NAN
b.astype(np.float)
print(b)
b[np.isnan(b)]=0
print(b)

你可能感兴趣的:(python机器学习,python,机器学习,numpy)