Python 数据科学 (1)——NumPy(4.Arrays 数据结构化)

本贴最后更新于 2192 天前,其中的信息可能已经时移俗易

在 numpy 中,提供了基本的数据类型,如 int64str。显然,基本数据类型是不能解决复杂的业务问题的,大多数情况下,我们使用的都是自定义的结构化数据。例如,描述一个人,用 str 存储其名字,int64 存储其地址等等。如果是一个公司,有很多员工,每一个属性将有大量的值。我们可以把这些值独立地存储在不同的 Arrays 中,用 numpy 仍然可以进行计算,但却把相关性给丢弃了,这显然得不偿失。我们需要呼唤更高级的数据结构。

类似于定义 np.zeros(4, dtype=int) 基本数据类型,我们可以在矩阵中定义复合类型:

In [3]: data = np.zeros(4, dtype={'names':('name', 'age', 'weight'), ...: 'formats':('U10', 'i4', 'f8')}) In [4]: data Out[4]: array([('', 0, 0.), ('', 0, 0.), ('', 0, 0.), ('', 0, 0.)], dtype=[('name', '<U10'), ('age', '<i4'), ('weight', '<f8')])

紧接着,把数据导入到定义好的结构中

In [5]: name = ['Alice', 'Bob', 'Cathy', 'Doug'] ...: age = [25, 45, 37, 19] ...: weight = [55.0, 85.5, 68.0, 61.5] In [6]: data['name'] = name ...: data['age'] = age ...: data['weight'] = weight

作为结果,我们可以观察到 data 中存储了结构化的数据

In [7]: data Out[7]: array([('Alice', 25, 55. ), ('Bob', 45, 85.5), ('Cathy', 37, 68. ), ('Doug', 19, 61.5)], dtype=[('name', '<U10'), ('age', '<i4'), ('weight', '<f8')])

这方便了我们对数据的操作

In [8]: data['name'] Out[8]: array(['Alice', 'Bob', 'Cathy', 'Doug'], dtype='<U10') In [9]: data[0] Out[9]: ('Alice', 25, 55.) In [10]: data[-1]['name'] Out[10]: 'Doug'

创建结构化矩阵

使用字典

In [11]: np.dtype({'names':('name', 'age', 'weight'), ...: 'formats':('U10', 'i4', 'f8')}) Out[11]: dtype([('name', '<U10'), ('age', '<i4'), ('weight', '<f8')])

或者,为了清晰,使用 numpy 的指定类型

np.dtype({'names':('name', 'age', 'weight'), 'formats':((np.str_, 10), int, np.float32)})

使用元组

In [12]: np.dtype([('name', 'S10'), ('age', 'i4'), ('weight', 'f8')]) Out[12]: dtype([('name', 'S10'), ('age', '<i4'), ('weight', '<f8')])

如过名称不重要的话,直接使用类型定义

In [13]: np.dtype('S10,i4,f8') Out[13]: dtype([('f0', 'S10'), ('f1', '<i4'), ('f2', '<f8')])

以下是类型简写表:

字符 描述
'b' 字节 np.dtype('b')
'i' 有符号整数 np.dtype('i4') == np.int32
'u' 无符号整数 np.dtype('u1') == np.uint8
'f' 浮点 np.dtype('f8') == np.int64
'c' 复数 np.dtype('c16') == np.complex128
'S''a' 字符串 np.dtype('S5')
'U' Unicode 字符串 np.dtype('U') == np.str_
'V' 原始数据(无效) np.dtype('V') == np.void

更高级的复合类型

使用嵌套,可以创建出更高级高级的数据类型:

In [14]: tp = np.dtype([('id', 'i8'), ('mat', 'f8', (3, 3))]) In [15]: np.zeros(1, dtype=tp) Out[15]: array([(0, [[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]])], dtype=[('id', '<i8'), ('mat', '<f8', (3, 3))])

记录矩阵

回顾之前的数据结构物 data,如果要获取所有的 age,我们只能

In [16]: data['age'] Out[16]: array([25, 45, 37, 19], dtype=int32)

此外,我们可以使用类 recarray 来创建视图,这样就可以像访问属性一样访问字典数据:

In [17]: data_rec = data.view(np.recarray) ...: data_rec.age Out[17]: array([25, 45, 37, 19], dtype=int32)

此外,我们还将获得额外的效率提升:

In [18]: %timeit data['age'] ...: %timeit data_rec['age'] ...: %timeit data_rec.age 138 ns ± 1.25 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) 2.92 µs ± 35.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 3.72 µs ± 18 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

迎接 pandas

对于处理结构化数据,pandas 包是一个更好的选择。

  • 数据科学
    7 引用 • 1 关注
  • numpy
    9 引用 • 1 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    556 引用 • 675 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...