首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python数据分析之NumPy(基础篇)

Python数据分析之NumPy(基础篇)

作者头像
AI异构
发布2020-07-29 11:10:36
1.5K0
发布2020-07-29 11:10:36
举报
文章被收录于专栏:AI异构AI异构

Numpy 是 Python 的一个科学计算包,包含了多维数组以及多维数组的操作

关于Numpy需要知道的几点:

  • NumPy 数组在创建时有固定的大小,不同于Python列表(可以动态增长)。更改ndarray的大小将创建一个新的数组并删除原始数据
  • NumPy 数组中的元素都需要具有相同的数据类型,因此在存储器中将具有相同的大小。数组的元素如果也是数组(可以是 Python 的原生 array,也可以是 ndarray)的情况下,则构成了多维数组。
  • NumPy 数组便于对大量数据进行高级数学和其他类型的操作。通常,这样的操作比使用Python的内置序列可能更有效和更少的代码执行

ndarray的内存结构

Numpy 的核心是ndarray对象,这个对象封装了同质数据类型的n维数组。起名 ndarray 的原因就是因为是 n-dimension-array 的简写。

import numpy as np
a = np.array([[0,1,2],[3,4,5],[6,7,8]], dtype=np.float32)

我们来看一下ndarray如何在内存中储存的:关于数组的描述信息保存在一个数据结构中,这个结构引用两个对象,一块用于保存数据的存储区域和一个用于描述元素类型的dtype对象。

数据存储区域保存着数组中所有元素的二进制数据,dtype对象则知道如何将元素的二进制数据转换为可用的值。数组的维数、大小等信息都保存在ndarray数组对象的数据结构中。 strides中保存的是当每个轴的下标增加1时,数据存储区中的指针所增加的字节数。例如图中的strides为12,4,即第0轴的下标增加1时,数据的地址增加12个字节:即a[1,0]的地址比a[0,0]的地址要高12个字节,正好是3个单精度浮点数的总字节数;第1轴下标增加1时,数据的地址增加4个字节,正好是单精度浮点数的字节数。

Numpy数组初始化

可以调用np.array去从list初始化一个数组:
a = np.array([1, 2, 3])  # 1维数组
print(type(a), a.shape, a[0], a[1], a[2])
a[0] = 5                 # 重新赋值
print(a)
<class 'numpy.ndarray'> (3,) 1 2 3
[5 2 3]
b = np.array([[1,2,3],[4,5,6]])   # 2维数组
print(b)
[[1 2 3]
 [4 5 6]]
print(b.shape)  #可以看形状(非常常用!)
print(b[0, 0], b[0, 1], b[1, 0])
(2, 3)
1 2 4
一些内置的创建数组的函数
a = np.zeros((2,2))  # 创建2x2的全0数组
print(a)
[[ 0.  0.]
 [ 0.  0.]]
b = np.ones((1,2))   # 创建1x2的全1数组
print(b)
[[ 1.  1.]]
c = np.full((2,2), 7) # 定值数组
print(c)
[[7 7]
 [7 7]]
d = np.eye(2)        # 对角矩阵(对角元素为1)
print(d)
[[ 1.  0.]
 [ 0.  1.]]
e = np.random.random((2,2)) # 2x2的随机数组(矩阵)
print(e)
[[ 0.72776966  0.94164821]
 [ 0.04652655  0.2316599 ]]
f = np.empty((2,3,2)) # empty是未初始化的数据,默认为0
print(f)
print(f.shape)
[[[ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]]
 [[ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]]]
(2, 3, 2)
g = np.arange(15) # 用arange可以生成连续的一串元素
print(g)
print(g.shape)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]
(15,)

Numpy数组数据类型

我们可以用dtype来看numpy数组中元素的类型:

x = np.array([1, 2])  # numpy构建数组的时候自己会确定类型
y = np.array([1.0, 2.0])
z = np.array([1, 2], dtype=np.int64)# 指定用int64构建

print(x.dtype, y.dtype, z.dtype)
int64 float64 int64
使用astype复制数组并转换数据类型
int_arr = np.array([1,2,3,4,5])
float_arr = int_arr.astype(np.float)
print(int_arr.dtype)
print(float_arr.dtype)
int32
float64
使用astype将float转换为int时小数部分被舍弃
float_arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
int_arr = float_arr.astype(dtype = np.int)
print(int_arr)
[ 3 -1 -2  0 12 10]
使用astype把字符串转换为数组,如果失败抛出异常。
str_arr = np.array(['1.25', '-9.6', '42'], dtype = np.string_)
float_arr = str_arr.astype(dtype = np.float)
print(float_arr)
[  1.25  -9.6   42.  ]
astype使用其它数组的数据类型作为参数
int_arr = np.arange(10)
float_arr = np.array([.23, 0.270, .357, 0.44, 0.5], dtype = np.float64)
print(int_arr.astype(float_arr.dtype)) #转换为浮点类型 [ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.]
print(int_arr[0], int_arr[1]) # 0 1
[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.]
0 1

Numpy的复制和视图

当计算和操作数组时,它们的数据有时被复制到新的数组中,有时不复制。这里我们做个区分。

完全不复制

简单赋值不会创建数组对象或其数据的拷贝。

a = np.arange(6)
print(a)
b = a
print(id(a))
print(id(b)) # id(a)和id(b)结果相同
b.shape =  3,2
print(a.shape) # 修改b形状,结果a的形状也变了
[0 1 2 3 4 5]
3169669797808
3169669797808
(3, 2)
视图或浅复制

不同的数组对象可以共享相同的数据。view方法创建一个新数组对象,该对象看到相同的数据。与前一种情况不同,新数组的维数更改不会更改原始数据的维数,但是新数组数据更改后,也会影响原始数据

a = np.arange(6)
c = a.view()
print(c is a) #False
print(c.base is a) #True
print(c.flags.owndata) #False
c.shape =(2,3)
print(a.shape) #(6,)
c[0,1] = 1234
print(a) # [   0 1234    2    3    4    5]
False
True
False
(6,)
[   0 1234    2    3    4    5]
深复制

copy方法生成数组及其数据的完整拷贝。

a = np.arange(6)
d = a.copy() # 一个完整的新的数组
print(d is a)
print(d.base is a )
d[0] = 9999
print(a) # 修改数组 d 的值,a不会受影响
False
False
[0 1 2 3 4 5]

Numpy数组取值和赋值

切片
import numpy as np

# 创建一个如下格式的3x4数组
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])

# 在两个维度上分别按照[:2]和[1:3]进行切片,取需要的部分
# [[2 3]
#  [6 7]]
b = a[:2, 1:3]
print(b)
[[2 3]
 [6 7]]
# 创建3x4的2维数组/矩阵
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
print(a)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

多维数组可以从各个维度同时切片

row_r1 = a[1, :]    # 第2行,但是得到的是1维输出(列向量)
row_r2 = a[1:2, :]  # 1x2的2维输出
row_r3 = a[[1], :]  # 同上
print(row_r1, row_r1.shape) #[5 6 7 8] (4,)
print(row_r2, row_r2.shape) #[[5 6 7 8]] (1, 4)
print(row_r3, row_r3.shape) #[[5 6 7 8]] (1, 4)
[5 6 7 8] (4,)
[[5 6 7 8]] (1, 4)
[[5 6 7 8]] (1, 4)
# 试试在第2个维度上切片也一样的:
col_r1 = a[:, 1]
col_r2 = a[:, 1:2]
print(col_r1, col_r1.shape) #[ 2  6 10] (3,)
print()
print(col_r2, col_r2.shape)
[ 2  6 10] (3,)
[[ 2]
 [ 6]
 [10]] (3, 1)
自由地取值和组合
a = np.array([[1,2], [3, 4], [5, 6]])

# 其实意思就是取(0,0),(1,1),(2,0)的元素组起来
print(a[[0, 1, 2], [0, 1, 0]])

# 下面这个比较直白啦
print(np.array([a[0, 0], a[1, 1], a[2, 0]]))
[1 4 5]
[1 4 5]
# 再来熟悉一下
# 先创建一个2维数组
a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
print(a)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
# 用下标生成一个向量
b = np.array([0, 2, 0, 1])

print(a[np.arange(4), b])  # Print "[ 1  6  7 11]"
[ 1  6  7 11]
# 既然可以取出来,我们当然可以对这些元素操作
a[np.arange(4), b] += 10
print(a)
[[11  2  3]
 [ 4  5 16]
 [17  8  9]
 [10 21 12]]
用条件判定去取值
a = np.array([[1,2], [3, 4], [5, 6]])

bool_idx = (a > 2)  # 就是判定一下是否大于2

print(bool_idx)  # 返回一个布尔型的3x2数组
[[False False]
 [ True  True]
 [ True  True]]
# 用刚才的布尔型数组作为下标就可以去除符合条件的元素啦
print(a[bool_idx])

# 其实一句话也可以完成是不是?
print(a[a > 2])
[3 4 5 6]
[3 4 5 6]
总结

参考

[numpy指南]http://docs.scipy.org/doc/numpy/reference/

[numpy ndarray详解]https://danzhuibing.github.io/py_numpy_ndarray.html

[NumPy-快速处理数据]http://old.sebug.net/paper/books/scipydoc/numpy_intro.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI异构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ndarray的内存结构
  • Numpy数组初始化
    • 可以调用np.array去从list初始化一个数组:
      • 一些内置的创建数组的函数
      • Numpy数组数据类型
        • 使用astype复制数组并转换数据类型
          • 使用astype将float转换为int时小数部分被舍弃
            • 使用astype把字符串转换为数组,如果失败抛出异常。
              • astype使用其它数组的数据类型作为参数
              • Numpy的复制和视图
                • 完全不复制
                  • 视图或浅复制
                    • 深复制
                    • Numpy数组取值和赋值
                      • 切片
                        • 自由地取值和组合
                          • 用条件判定去取值
                            • 总结
                            • 参考
                            相关产品与服务
                            数据保险箱
                            数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档