【问题标题】:Writing a numpy.array() from a list of namedtuples从命名元组列表中写入 numpy.array()
【发布时间】:2018-12-01 23:59:58
【问题描述】:

我有一个命名元组列表,我想将其写入一个 numpy 数组。 元组具有属性“colors”(一组两种颜色)和“number”(整数)属性,格式如下:

from collections import namedtuple
import numpy as np

NamedTuple = namedtuple('tuple',['colors','number'])

L = [NamedTuple({'violet', 'blue'}, 4),  
    NamedTuple({'orange', 'blue'}, 1),  
    NamedTuple({'green', 'blue'}, 3),  
    NamedTuple({'orange', 'red'}, 2)]
L
>>>[tuple(colors={'blue', 'violet'}, number=4)...]
L[3].colors
>>>{'orange', 'red'}

我想从 L 写,例如,一个 2x2 数组,这样:

Array[1][1].colors
>>>{'orange', 'red'}

在做

Array = numpy.array(L)
>>>[[{'blue', 'violet'} 4]
   [{'blue', 'orange'} 1]
   [{'blue', 'green'} 3]
   [{'red', 'orange'} 2]

给我一​​个元组数组,而不是命名元组,它有'没有属性'颜色''
更糟糕的是,如果我尝试将 Array 重塑为 2x2,我会发现我的 namedtuples 的每个属性都被写为数组中的不同对象。

numpy.reshape(Array,(2,2))
>>>...error...
>>>'ValueError: cannot reshape array of size 8 into shape (2,2)'

我会认为上面的数组大小为 4?

如何在不改变命名元组的情况下获得一个命名元组数组,以便可以从数组中的每个元素调用不同的属性?

我想使用 namedtuples 作为我的数据结构的原因是调用每个对象的 .color 或 .number 属性既简单又易读。
我想使用 numpy 数组而不是标准嵌套列表的原因是因为这个数组将成为整个项目中的动态对象,经常会被搜索和更改,而且我知道 python 的标准列表对于这些来说有多糟糕东西。
就上下文而言,我最终试图构建一个程序来玩我自己发明的纸牌游戏。 namedtuples 用它们的颜色和数字表示卡片。阵列代表玩家可以更改和移动的卡片画面。这些命名元组将被改组很多,我不想担心它们的数据结构会被改变。

【问题讨论】:

    标签: python arrays numpy namedtuple


    【解决方案1】:

    因为NamedTupletuple 的子类,所以从L 构造对象数组会产生一个(n,2) 数组,就像我们将它作为元组列表或列表列表一样:

    In [4]: np.array(L, object)
    Out[4]: 
    array([[{'violet', 'blue'}, 4],
           [{'blue', 'orange'}, 1],
           [{'blue', 'green'}, 3],
           [{'red', 'orange'}, 2]], dtype=object)
    In [5]: _.shape
    Out[5]: (4, 2)
    

    这里有一个技巧 - 首先将 None 对象附加到列表中:

    In [13]: arr = np.array(L+[None], object)[:-1]
    In [14]: arr
    Out[14]: 
    array([tuple(colors={'violet', 'blue'}, number=4),
           tuple(colors={'blue', 'orange'}, number=1),
           tuple(colors={'blue', 'green'}, number=3),
           tuple(colors={'red', 'orange'}, number=2)], dtype=object)
    In [15]: arr.shape
    Out[15]: (4,)
    In [16]: arr = np.reshape(arr,(2,2))
    In [17]: arr
    Out[17]: 
    array([[tuple(colors={'violet', 'blue'}, number=4),
            tuple(colors={'blue', 'orange'}, number=1)],
           [tuple(colors={'blue', 'green'}, number=3),
            tuple(colors={'red', 'orange'}, number=2)]], dtype=object)
    

    我在之前的问题中发现frompyfunc 是访问此类数组元素的最方便(也是最快)的工具。

    Most efficient way to set attributes on objects in array

    In [18]: np.frompyfunc(lambda x: x.colors, 1,1)(arr)
    Out[18]: 
    array([[{'violet', 'blue'}, {'blue', 'orange'}],
           [{'blue', 'green'}, {'red', 'orange'}]], dtype=object)
    

    要构造一个结构化数组,我们可以这样做:

    In [19]: arr1 = np.array(L, dtype=[('colors', object), ('number', int)])
    In [20]: arr1
    Out[20]: 
    array([({'violet', 'blue'}, 4), ({'blue', 'orange'}, 1),
           ({'blue', 'green'}, 3), ({'red', 'orange'}, 2)],
          dtype=[('colors', 'O'), ('number', '<i8')])
    

    NamedTupletuple 的子类,因此它可以作为数据输入(例如元组列表)。

    In [22]: arr1['colors']
    Out[22]: 
    array([{'violet', 'blue'}, {'blue', 'orange'}, {'blue', 'green'},
           {'red', 'orange'}], dtype=object)
    In [23]: arr1['number']
    Out[23]: array([4, 1, 3, 2])
    

    初始化一维数组并分配元素有效:

    In [30]: arr2 = np.empty(4, object)
    In [31]: arr2[:] = L
    In [32]: arr2
    Out[32]: 
    array([tuple(colors={'violet', 'blue'}, number=4),
           tuple(colors={'blue', 'orange'}, number=1),
           tuple(colors={'blue', 'green'}, number=3),
           tuple(colors={'red', 'orange'}, number=2)], dtype=object)
    

    填写np.empty((2,2), object) 会有点棘手。


    我可以使用结构化数组(或任何其他输入列表对)的字段构造一个对象数组:

    In [44]: np.frompyfunc(NamedTuple, 2,1)(arr1['colors'], arr1['number'])
    Out[44]: 
    array([tuple(colors={'violet', 'blue'}, number=4),
           tuple(colors={'blue', 'orange'}, number=1),
           tuple(colors={'blue', 'green'}, number=3),
           tuple(colors={'red', 'orange'}, number=2)], dtype=object)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 2016-09-07
      相关资源
      最近更新 更多