5

关于numpy.array和列表list的区别

 3 years ago
source link: https://oldpan.me/archives/difference-numpy-array-list
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

关于numpy.array和列表list的区别

Oldpan 2021年1月17日 0条评论 136次阅读 0人点赞

《关于numpy.array和列表list的区别》

某一天写代码的时候突然遇到一个场景,需要批量对标注信息box进行操作(box包括[x1,y1,x2,y2])。

最简单的操作就是,for循环遍历将box一个一个存到list中最终转化为numpy的二维数组进行操作:

bboxes = []
for k in range(num_objs):
    ann = anns[k]
    bbox = self._coco_box_to_bbox(ann['bbox'])
    # 构造array的时候需要 [[]] 二维方式构造
    sbbox = np.array([[bbox[0], bbox[1], bbox[2], bbox[3]]])
    bboxes.append(sbbox)

if bboxes != []:
    bboxes = np.concatenate(bboxes, 0)

需要注意的是我们在构造numpy数组的时候,需要提前把二维这个维度信息告诉np.array:

>>> import numpy as np
>>> a = np.array([1,2,3,4])
>>> b = []
>>> b.append(a)
>>> b.append(a)
>>> b
[array([1, 2, 3, 4]), array([1, 2, 3, 4])]
>>> c = np.concatenate(b)
>>> c
array([1, 2, 3, 4, 1, 2, 3, 4])
>>> c.shape # 此时concat后的c还是一维的
(8,)
# 这样
>>> a = np.array([[1,2,3,4]])  # 需要提前指明2维
>>> b = []
>>> b.append(a)
>>> b.append(a)
>>> b
[array([[1, 2, 3, 4]]), array([[1, 2, 3, 4]])]
>>> c = np.concatenate(b)
>>> c
array([[1, 2, 3, 4],
       [1, 2, 3, 4]])
>>> c.shape # 此时concat后的维度才是2维
(2, 4)  

np.concatenate后bboxes的维度是(N,5),此时可以通过这种方式去批量处理x1,y1,x2,y2

offset_x = 1
offset_y = 2
bboxes[:, 0] = bboxes[:, 0] + offset_x
bboxes[:, 1] = bboxes[:, 1] + offset_y
bboxes[:, 2] = bboxes[:, 2] + offset_x
bboxes[:, 3] = bboxes[:, 3] + offset_y

numpy的array可以这样操作,但是对于list来说是不行的:

>>> a=[[1,2,3],[4,5,6]]
>>> a[0]    #取第一行是可以的
[1, 2, 3]
>>> a[:,0]  #尝试用数组索引方式失败
TypeError: list indices must be integers or slices, not tuple

这是因为python中的list和numpy中的array是完全不一样的两个东西,list可以存放不同类型的数据,比如int、float和str,甚至布尔型;而一个numpy数组中存放的数据类型必须全部相同,例如int或float。

在list中的数据类型保存的是数据的存放的地址,即指针而非数据(底层是C语言,这样想想也很正常),例如a=[1,2,3,4]需要4个指针和四个数据,增加了存储和消耗cpu,而a=np.array([1,2,3,4])只需要存放四个数据,读取和计算更加方便。

所以列表List可以存放不同类型的数据,因此列表中每个元素的大小可以相同,也可以不同,所以也就不支持一次性读取一列。即使是对于标准的二维数字列表([[1,2,3,4]]这种),所以纯数字的我们最好都使用numpy的数据类型去操作。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK