为了账号安全,请及时绑定邮箱和手机立即绑定

向量化列表列表的函数

向量化列表列表的函数

哈士奇WWW 2022-10-11 10:29:43
我需要使用具有以下特征的高效 python 数据结构:像列表一样堆叠很多次的结构列表长度没有规律有固定的深度始终具有相同的数据类型。这是一个深度为 3 的示例[[[1,2] , [3,4,5]], [[6,7,8] , [9] , [10] , [11,12]], [[13] , [14,15] , [16,17,18]]大多数情况下,该结构将包含 numpy 数组或数字,但它也可能是另一个对象,如 dict。但是,给定结构中的数据类型始终相同。我的主要问题是我需要将函数应用于此类结构(如“矢量化”函数)。我希望我的函数采用与参数具有相同形状的几个结构,并返回其他结构。您认为最有效的方法是:使用堆叠列表或堆叠 numpy 数组:那么如何在不使用许多for循环的情况下编写高效的“矢量化”函数?使用单个数组并分别存储形状(我目前正在研究这个)创建自己的结构,但我怎样才能使它比堆叠列表更有效?或者也许你知道一个可以帮助我的图书馆?我特别在寻找 RAM 效率。我希望我已经把我的问题说清楚了,谢谢你的帮助。
查看完整描述

2 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

如果您想获得真正的矢量化处理,则需要使用诸如 numpy 之类的库。但是这些可能会限制您可以支持的数据类型,以便允许 GPU 进行处理。


在任何一种情况下,您都可以使用字典来展平结构并促进结构元素的批处理。这将是一个以元组作为键的字典,其中元组中的每个条目表示该级别的值索引:


例如:


  [ [1,2] ,   [3,4,5] ],

  [ [6,7,8] , [9] ,     [10] ,     [11,12] ],

  [ [13] ,    [14,15] , [16,17,18] ]

]

可以在这样的字典中表示为:


  (0,0,0) : 1,

  (0,0,1) : 2,

  (0,1,0) : 3,

  (0,1,1) : 4,

  (0,1,2) : 5,

  (1,0,0) : 6,

  (1,0,1) : 7,

  (1,0,2) : 8,

  (1,1,0) : 9,

  (1,2,0) : 10,

  (1,3,0) : 11,

  (1,3,1) : 12,

  (2,0,0) : 13,

  (2,1,0) : 14,

  (2,1,1) : 15,

  (2,1,0) : 16,

  (2,1,1) : 17,

  (2,1,2) : 18

}

这也可以使用两个数组(一个用于级别索引,一个用于数据)在 numpy 中表示


这种类型的结构之间的处理将提供树结构中叶值的快速遍历,同时保持分支之间的关系。


例如:


# sum of values under second branch:

result = sum( value for level,value in data.items() if level[0] == 1 )


# or using numpy:

result = np.sum(data[levels[:,0]==1]) 


# adding two structures:

result = { k:data1.get(k,0)+data2.get(k,0) for k in set((*data1,*data2)) }


# or using numpy (assuming same levels in both structures)

resultLevels, resultData = levels1,data1+data2


# numpy adding structures with different levels is a bit more involved

# but still feasible.



查看完整回答
反对 回复 2022-10-11
?
慕斯709654

TA贡献1840条经验 获得超5个赞

谢阿兰 T。


我已经使用了你的想法并编写了这个类来处理我的数据。这样,我可以像使用 numpy 数组一样使用 slice 访问我的元素,并且可以将 data 参数(扁平数据)与 numpy 矢量化函数一起使用:


class DataStructure():

    __slots__ = ["data", "positions"]


    def __init__(self, data, place):

        self.data = np.array(data)

        self.positions = np.array(place)


    def __getitem__(self, item):

        item = (item,) if not isinstance(item, tuple) else item

        mask = np.full((len(self.positions),), True)

        for i, selection in enumerate(item):

            if not isinstance(selection, slice):

                mask &= self.positions[:, i] == selection

            else:

                start, stop, step = selection.indices(len(self.positions))

                mask &= np.isin(self.positions[:,i], range(start,stop,step))

        return self.data[mask]

PS:不要犹豫告诉我它是否可以优化,特别是我使用切片。


查看完整回答
反对 回复 2022-10-11
  • 2 回答
  • 0 关注
  • 106 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号