Python 多次包装代替状态变化

Python 以多次包装代替状态变化,首先考虑创建一个名为Ranked_X的命名元组子类,包含r_xranked_y两个属性。其中ranked_y是一个Ranked_Y实例,Ranked_Y包含两个属性:r_yraw,虽然易于构建,但难以处理,因为r_xr_y不在同一级结构中。下面介绍一个略复杂的包装过程,以得到简单的结果数据结构。

我们希望输出数据如下所示:

class Ranked_XY(NamedTuple):
    r_x: float
    r_y: float
    raw: Pair

该命名元组包含多个对等的属性,这种结构比深层嵌套结构易于处理。在某些应用中,需要多次变换数据,这里只有两次变换:对xy求等级值。整个过程分为两步:首先像前面那样简单包装,然后是更通用的“拆包-再包装”。

基于y等级排序进行x-y等级排序如下所示:

def rank_xy(pairs: Sequence[Pair]) -> Iterator[Ranked_XY]:
    return (
        Ranked_XY(
            r_x=r_x, r_y=rank_y_raw[0], raw=rank_y_raw[1])
        for r_x, rank_y_raw in
            rank(rank_y(pairs), lambda r: r.raw.x)
    )

首先通过rank_y()函数创建Rank_Y对象,然后对这些对象应用rank()函数,基于原始数据中的x属性求等级值。该函数返回一个二元组:x等级值和Rank_Y对象。最后基于x等级值r_xy等级值rank_y_raw[0]和原始对象rank_y_raw[1]创建了Ranked_XY对象。

第二个函数展示了为元组添加数据的一种更通用的方法,Ranked_XY对象的构建过程演示了如何从原有数据中拆包,并再次打包形成更复杂的结构,这是向元组中添加新变量的一种常用方法。

样本数据如下所示:

>>> data = (Pair(x=10.0, y=8.04), Pair(x=8.0, y=6.95),
... Pair(x=13.0, y=7.58), Pair(x=9.0, y=8.81),
etc.
... Pair(x=5.0, y=5.68))

可创建等级对象如下所示:

>>> list(rank_xy(data))
[Ranked_XY(r_x=1.0, r_y=1.0, raw=Pair(x=4.0, y=4.26)),
 Ranked_XY(r_x=2.0, r_y=3.0, raw=Pair(x=5.0, y=5.68)),
 Ranked_XY(r_x=3.0, r_y=5.0, raw=Pair(x=6.0, y=7.24)),
etc.
 Ranked_XY(r_x=11.0, r_y=10.0, raw=Pair(x=14.0, y=9.96))]

有了xy的等级值,就可以计算斯皮尔曼等级顺序相关度了,最终可以根据原始数据算出斯皮尔曼等级相关系数。

前面的多次求等级值的方法涉及拆解元组并创建新的包含附加属性的单层元组,当需要从输入数据中计算多个目标值时,这是一种常用的方法。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程