数据分析(二)--numpy

numpy

numpy的主要对象是同种元素的多维数组。

numpy底层是用C语言实现的。

面试

数组和列表有什么区别?

结构同样都是[元素1,元素2,元素3 … ]。

在C语言、java中叫做数组;在python中叫做列表。

python中的列表可以存储不同类型的对象;C语言中的数组只能存放相同类型的数据。

导包

import numpy as np

一、numpy介绍

numpy是用于数据科学计算的基础,不但能够完成科学计算任务,还能被用作高效地多维数据容器。用于存储和处理大型矩阵。

python提供了一个 array 模块,和 list 不同,它直接保存数值,但是python的 array模块不支持多维,也没有各种运算函数。

numpy弥补了这一遗憾。numpy 提供了一种存储单一数据类型的多维数组–ndarray。

轴(axes)–维度

秩(rank)–轴的个数

(一)array创建数组

1.一维数组

arr1 = np.array([1,2,3])
print('arr1的维度:',arr1.shape)    #(3,)
print('arr1的秩:',arr1.ndim)    # 1

2.二维数组

arr2 = np.array([[1],[2],[3]])
print('arr2的维度:',arr2.shape)    # (3, 1)
print('arr2的秩:',arr2.ndim)    # 2

结论

一位数组的秩为1,二维数组的秩为2

即arr.ndim = len(arr.shape)

(二)常用属性

1.秩:ndim

2.维度:shape

arr3 = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(arr3.shape)
print(arr3.ndim)
print(len(arr3.shape))

3.数组元素的总个数size

print(arr3.size)

4.数组元素的类型dtype

print(arr3.dtype)    # int32
arr4 = np.array([0.1,0.2,0.3])
print(arr4.dtype)    # float64

5.每个元素的字节大小itemsize

一个字节(byte)=8 位(bit)

print(arr3.itemsize)    # 4
print(arr4.itemsize)    # 8

6.缓冲区:data

arr5 = np.array([1,2,3])
print(arr5.dtype)
print(arr5.itemsize)
print(arr5.data)    # <memory at 0x00000000038F14C8>
print(arr5[0])

索引从0开始的原因:

arr5就是arr5.data,即存储地址的别名

[]中的数字,表示取指定元素,需要跨进的单元

取第一个元素,不用跨进,所以为0
在这里插入图片描述

(三)创建数组的方法

1.使用array()

# def array(p_object, dtype=None, copy=True, order='K', subok=False, ndmin=0):
# p_onject--接收一个array
# dtype--接受一个data-type,表示数组所需要的数据类型,如果没有给定,则根据传入元素的,指定随需要的最小数据类型
arr1 = np.array([1,2,3,4])
print(arr1)
arr2 = np.array([[1,2],[3,4]])
print(arr2)
arr3 = np.array([(1,2),(3,4)])
print(arr3)
arr4 = np.array([1,2,3,4],dtype=np.float64)
print(arr4)

2.使用arange()

# def arange(start=None, stop=None, step=None, dtype=None):
# 值域[start,stop)
arr5 = np.arange(0,1,0.1)
print(arr5)

3.使用linspace()

# def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
# 值域[start,stop],num--元素数量
arr6 = np.linspace(0.1,1,10)
print(arr6)

4.使用logspace()–等比

# def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None):
arr7 = np.logspace(1,3,3)
print(arr7)
arr8 = np.logspace(1,10,10,base=2)
print(arr8)

5.使用zeros()–全0数组

# def zeros(shape, dtype=None, order='C')
arr9 = np.zeros((2,3))
print(arr9)

6.使用ones()–全1数组

# def ones(shape, dtype=None, order='C'):
arr10 = np.ones((2,3))
print(arr10)

7.使用empty()

创建一个内容随机并且依赖于内存状态的数组。

print(np.empty((2,3)))

8.使用eye()–单位数组

arr11 = np.eye(3)
print(arr11)
# [[ 1.  0.  0.]
#  [ 0.  1.  0.]
#  [ 0.  0.  1.]]
print(np.eye(2,3))
# [[ 1.  0.  0.]
#  [ 0.  1.  0.]]

9.使用diag()

arr12 = np.diag([1,2,3,4])
print(arr12)
# [[1 0 0 0]
#  [0 2 0 0]
#  [0 0 3 0]
#  [0 0 0 4]]

练习

1.生成一个3*5的数组,数组元素为0-14之间的整数

方法1:

arr1 = np.arange(0,15)
arr1.shape = (3,5)
print(arr1)

方法2:

arr2 = np.arange(0,15).reshape(3,5)
print(arr2)

2.输出数据的维度、秩、元素类型、元素个数

print('维度:',arr1.shape)
print('秩:',arr1.ndim)
print('元素类型:',arr1.dtype)
print('元素个数:',arr1.size)

(四)生成随机数组

1.random.random(n)

值域[0,1),n表示生成元素的个数。

arr1 = np.random.random(3)
print(arr1)
arr2 = np.random.random(15).reshape((3,5))
print(arr2)

2.random.rand(m,n,…)

表示生成一个m*n*...的多维数组,值域为[0,1)。

arr3 = np.random.rand(2,3)

3.random.randn(n)

生成正态随机数,n表示生成元素的个数。

arr4 = np.random.randn(4)
print(arr4)
import matplotlib.pyplot as plt
plt.hist(arr4)
plt.show()

发现并没有看出什么正态分布的趋势。

这就涉及到了大数定理。

把n的值变为1000试试?

arr4 = np.random.randn(1000)
import matplotlib.pyplot as plt
plt.hist(arr4)
plt.show()

这次就有正态分布的效果了
在这里插入图片描述

4.random.randint(a,b,size=(m,n))

# def randint(low, high=None, size=None, dtype='l'):
# 值域[a,b],维度(m,n)的数组
arr5 = np.random.randint(1,10,size=(2,5))
print(arr5)

5.扩展:random模块常用随机生成函数

normal():生成正态(高斯)分布的随机数

# def normal(loc=0.0, scale=1.0, size=None):
# loc:float--概率分布的均值,对应着整个分布的中心center
# scale:float--概率分布的标准差,对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高
# size:int or tuple of ints--输出的shape,默认为None,只输出一个值

beta():生成beta分布的随机数

在概率论中,贝塔分布,也称B分布,是指一组定义在(0,1)区间的连续概率分布。
在这里插入图片描述

chisqusre():生成卡方分布的随机数

gamma():生成gamma分布的随机数

伽玛分布(Gamma Distribution)是统计学的一种连续概率函数,是概率统计中一种非常重要的分布。“指数分布”和“χ2分布”都是伽马分布的特例。

二、数据类型

(一)基本数据类型

(二)数据类型转换

# 例
print(np.float64(42))
print(np.int32(42.0))
print(np.bool(1))    # 所有非零数据转换成bool类型都是True

(三)自定义数据类型

例:创建一个存储餐饮企业库存信息的数据类型

规定:

(1)用一个长度为40的字符串来记录商品的名称

(2)用一个64位整数来记录商品库存

(3)用一个64位单精度浮点型来记录商品的价格

df = np.dtype([('name',np.str_,40),('numitems',np.int64),('price',np.float64)])
print('df数据结构:',df)    # [('name', '<U40'), ('numitems', '<i8'), ('price', '<f8')]
# <U40--长度小于40的字符串,<i8--小于八字节的int类型
table1 = np.array([('tomatos',42,4.14),('cabbages',13,1.72)],dtype=df)
print(table1)
# 输出商品名
print(table1['name'])    # ['tomatos' 'cabbages']
print(table1[0],type(table1[0]))    # <class 'numpy.void'>
arr1 = np.array([1,2,3])
print(arr1[0],type(arr1[0]))    # <class 'numpy.int32'>

三、数据元素的访问

通过索引访问数组元素

(一)一维数组

arr1 = np.arange(10)
print(arr1)
print(arr1[0])
print(arr1[-1])
# 支持切片
print(arr1[3:5])
print(arr1[:5])
print(arr1[3:])

arr1[2:4] = 100,101    # 个数不对应,会报错
print(arr1)    # [  0   1 100 101   4   5   6   7   8   9]
print(arr1[1:-1:2])
print(arr1[5:1:-2])

注意:从后向前利用切片取数组中的元素时,步长为负。

(二)二维数组

arr2 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
print(arr2)
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
print(arr2[0][0])

例:取第一行,第3,4列的元素

1.切片

print(arr2[0][2:])

2.数组名[行索引,列索引]

print(arr2[0,2:])

3.数组名[(行下标),(列下标)]

说明:该种写法主要用于获取指定行或列的值;而切片写法,获取到的是连续的行或列的值。

print(arr2[(0,2),(1,3)])    # [ 2 12]
# 2--(0,2),12--(2,3)
# 也可以配合使用
print(arr2[(0,2),:])

(三)遮罩–mask

arr3 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
mask = np.array([1,0,1],dtype=np.bool)
print(mask)    # [ True False  True],True显示,False不显示
print(arr3[mask,2])
print(arr3[(True,False,True),2])

四、变换数组形态

(一)shape和reshape()

arr1 = np.arange(0,15)
arr1.shape = (3,5)
print(arr1)
arr2 = np.arange(0,15).reshape(3,5)
print(arr2)

(二)展平数组

1.ravel()

是reshape()函数的逆操作

注意:并不修改原数组,而是返回了一个新数组。

arr1 = np.arange(10000)
arr2 = arr1.reshape((100,100))
print(arr1)
print(arr2)
arr3 = arr2.ravel()
print(arr3)

tip1

如果输出的数组数量太大,在输出时,numpy自动省略中间部分,只打印两边元素。

如果不想省略,可以在打印前设置如下信息:

np.set_printoptions(threshold=np.NaN)
# 之后再打印
print(arr2)

2.flatten()

# 默认order='C'		
# 以行展平
arr3 = np.arange(10).reshape((2,5))
arr4 = arr3.flatten()
arr5 = arr3.ravel()
print(arr3)
print(arr4)
print(arr5)

# order='F'
# 以列展平
arr6 = np.array([[1,2],[3,4]])
arr7 = arr6.flatten(order='F')
print(arr7)

ravel()和flatten()

共同点

都是将多维数组展开为一维,输出结果相同。

不同点

flatten返回的是一份拷贝,强调的是数据。

ravel返回的是一份视图,侧重的是数据的展现,而不是数据本身。

例:

a1 = np.array([[1,2],[3,4]])
f_a = a1.flatten()
r_a = a1.ravel()
print(a1)
print('f_a:',f_a)
print('r_a:',r_a)
print('--------------------------------------------------------')
f_a[2] = 100
print('f_a:',f_a)
print(a1)    # flatten的数组元素发生变化不影响原数组

a1 = np.array([[1,2],[3,4]])
f_a = a1.flatten()
r_a = a1.ravel()
print(a1)
print('f_a:',f_a)
print('r_a:',r_a)
print('--------------------------------------------------------')
r_a[2] = 101
print('r_a:',r_a)
print(a1)    # ravel的数组元素变化,原数据也会同时发生变化

(三)组合/切割数组

1.组合

(1)hstack()和vstack()

arr1 = np.arange(1,6,2)
arr2 = np.arange(7,12,2)
print(arr1,arr2)    # [1 3 5] [ 7  9 11]
arr3 = np.hstack((arr1,arr2))
print(arr3)
# [ 1  3  5  7  9 11]
arr4 = np.vstack((arr1,arr2))
print(arr4)
# [[ 1  3  5]
#  [ 7  9 11]]

注意

如果两个数组,元素个数不相等,横向正常拼接,但纵向将会报错。

在stack函数中,参数为tuple,但其实list也是可以的。

arr1 = np.array([[1,1],[2,2]])
arr2 = np.array([[3,3],[4,4]])
arr3 = np.hstack((arr1,arr2))
arr4 = np.vstack((arr1,arr2))
print('arr1:\n',arr1)
# arr1:
#  [[1 1]
#  [2 2]]
print('arr2:\n',arr2)
# arr2:
#  [[3 3]
#  [4 4]]
print('arr3:\n',arr3)
# arr3:
#  [[1 1 3 3]
#  [2 2 4 4]]
print('arr4:\n',arr4)
# arr4:
#  [[1 1]
#  [2 2]
#  [3 3]
#  [4 4]]

(2)concatenate()和轴

axis–轴

# 横向拼接
arr5 = np.concatenate((arr1,arr2),axis=1)
print('arr5:\n',arr5)
# 纵向拼接
arr6 = np.concatenate((arr1,arr2),axis=0)
print('arr6:\n',arr6)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章