欢迎访问宙启技术站
智能推送

如何在Python中使用NamedTuple函数实现数据结构化

发布时间:2023-06-13 21:34:23

Python是一种高级编程语言,非常适合数据处理和分析。在Python中,我们经常需要使用数据结构来存储和操作数据。一个常见的问题是,如何实现可读性强、易于维护的数据结构呢?

Python官方的标准库提供了一个叫做NamedTuple的函数,可以非常方便地实现数据结构化。本文将介绍如何在Python中使用NamedTuple函数实现数据结构化。

一、NamedTuple函数简介

NamedTuple函数是Python 2.6中引入的一个新功能,它是一个工厂函数,用于创建一个带有命名字段的元组类型。它的定义如下:

namedtuple(typename, field_names, *, verbose=False, rename=False, module=None)

其中,typename是新创建的NamedTuple类型的名称,field_names是一个字符串列表,用于指定命名字段的名称。

这个函数创建的类实例支持所有元组的常用协议(遍历、索引、切片等),并且允许通过属性、位置或名称来访问其字段。

名为typeName的NamedTuple类型的常规语法(每个字段一行)在python中看起来像这样:

from collections import namedtuple

Name = namedtuple('Name', ['first', 'last'])

这将创建一个名为Name的NamedTuple类型,它有两个命名字段:first和last。

NamedTuple 对用户来说有以下几个优点:

1. 代码可读性更好

NamedTuple 使你能够给它的字段命名,而不是指定每个字段的索引。按名称引用字段通常比按索引更好的表达了字段的含义及顺序。

2. 更易于理解用户代码中涉及哪些元组类型。

因为 NamedTuple实例输出的字符串中包含类型名称(type name),用于指示你正在处理哪种类型的元组。

3. NamedTuple 是不可变的

NamedTuple 实例不支持对其字段的直接修改操作,这提高了程序的安全性。

二、NamedTuple函数的使用

NamedTuple 为元组提供了基本的易读性和灵活性,但它与其他元组类型之间 的区别,就是它允许您为每个元组中的字段命名。

命名元组支持与普通元组完全相同的操作,例如索引、迭代和切片。你可以直接使用点操作符使用命名元组的位置和名字两种访问方式。

下面我们先创建一个名为Point的NamedTuple类型,这个类型有两个命名字段 x 和 y。

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
pt = Point(1.0, 2.0)

有了这些,我们可以像预期的元组一样对pt进行操作,这里我举例一下:

使用 index 访问单个字段。

print(pt[0])
# 1.0
print(pt[1])
# 2.0

也可以使用点操作符访问单个字段。

print(pt.x)
# 1.0
print(pt.y)
# 2.0

如果你需要访问所有字段,可以像普通的元组一样,使用迭代。

for val in pt:
    print(val)
# 1.0
# 2.0

命名元组的其它方法:

1. _asdict()

as_dict = pt._asdict()
print(as_dict)
# OrderedDict([('x', 1.0), ('y', 2.0)])

2. _replace()

修改命名元组的字段

pt2 = Point(3.0, 4.0)
pt2 = pt2._replace(x=5.0)
print(pt2)  
# Point(x=5.0, y=4.0)

3. _fields

返回一个元组,包含字段名。

print(pt._fields)
# ('x', 'y')

三、NamedTuple函数的应用

1. 数据结构

NamedTuple 最常用的场景就是作为定义数据结构的一种方式。可以通过它轻松创建一些易于读写和理解的数据类型。

比如下面这个例子,我们用NamedTuple定义了一个Rectangle类型。

from collections import namedtuple

Rectangle = namedtuple('Rectangle', ['x0', 'y0', 'x1', 'y1'])

rect = Rectangle(100, 200, 300, 400)

这个Rectangle类型有4个字段,x0、y0、x1、y1。分别表示矩形的两个端点坐标。

我们也可以通过点操作符轻松地访问这些属性:

print(rect.x0, rect.y0, rect.x1, rect.y1)
# output: 100 200 300 400

2. 数据表格

在数据分析领域,NamedTuple 可以用来定义数据表格行数据的结构。

比如下面这个例子,我们可以用 NamedTuple 定义一个包含订单基本信息的数据表格结构 - OrderInfo。

from collections import namedtuple

OrderInfo = namedtuple('OrderInfo', ['order_id', 'user_name', 'order_time', 'total_price'])

这个数据表格包含4个字段,分别是 orderId、userName、orderTime、totalPrice。我们可以创建一个如下的订单数据:

order1 = OrderInfo('1001', 'userA', '2020-01-01', 1299.99)
order2 = OrderInfo('1002', 'userB', '2020-01-02', 1099.99)
order_list = [order1, order2]

现在,我们就可以方便的访问每个订单的某个属性,比如订单号:

for order in order_list:
    print(order.order_id)

同样的,也可以方便地通过各个字段的名称快速构建字典。

order_dict_list = [order._asdict() for order in order_list]
print(order_dict_list)

输出结果:

[{'order_id': '1001', 'user_name': 'userA', 'order_time': '2020-01-01', 'total_price': 1299.99}, {'order_id': '1002', 'user_name': 'userB', 'order_time': '2020-01-02', 'total_price': 1099.99}]

3. 表示位置信息

在地理信息计算中,NamedTuple可用来表示地理位置。比如下面这个例子,我们定义了一个名为 Location 的元组:

from collections import namedtuple

Location = namedtuple('Location', ['lat', 'lng'])

这个Location元组包含了经度和纬度两个字段,可以用来存储地图上的位置信息。

我们可以使用下面的方式来创建一个 Location 实例。

Beijing = Location(39.9037207, 116.4052147)

Location 实例就表示北京的位置信息。现在,我们就可以方便地对这个位置信息进行操作了。

比如,如果需要计算出距离北京 100 公里内的点坐标。我们只需要适当变化经纬度值即可。

import math

delta = 100 / 111.0 / 1000.0
lats = Beijing.lat + math.sin(0) * delta
lngs = Beijing.lng + math.cos(0) * delta / math.cos(Beijing.lat)
print('新的位置信息:{}'.format(Location(lats, lngs)))

这里我们使用 sin 和 cos 函数计算出了一个固定的偏移量,将北京位置信息沿着纬度和经度轴移动一定距离,得到新的位置信息。

四、总结

NamedTuple 是 Python 的一个非常强大的函数,它可以帮助我们非常容易地实现数据结构化,提高程序的可读性和安全性。

在本