numpy.ma是否允许屏蔽掩码数组中的子掩码数组?

时间:2013-07-19 00:23:59

标签: python arrays numpy pydev mask

我正在Python 2.7中编写一些代码(在eclipse,Mac OSX中使用pydev)来收集有关存储在xml文件中的大量卡信息的信息。这些卡片来自魔术聚会,并且都有非常相似的卡片结构(名称,播放成本,类型等)。

我使用蒙面数组来存储卡上的所有信息。这是我初始化以存储此信息的数组(在代码中遇到更多字段时添加:)

AllCards=numpy.ma.masked_all(2, dtype=[('Set','a128'),('Name','a128'),
                                       ('Cost','a128'),('CMC','a128'), 
                                       ('Color','a128'),('Type','a128'),
                                       ('Subtype','a128'),('Rarity','a128'),
                                       ('Rules','a512'),('Power','a128'),
                                       ('Toughness','a128'),('PT Box','a128'),
                                       ('Artist','a128'),('Flavor','a512'),
                                       ('MultiverseId','a128')])

我能够按照自己的意愿填充和屏蔽这个数组,但是当我开始使这个原始数组变得更复杂时,我遇到了一个特殊的问题。当诸如Faithful Squire之类的卡片具有比常规卡片更复杂的组件(翻转方面)时,它在xml中被编码为:

<card name="Faithful Squire" id="34905b29-481d-9e16-bc50-3b9f5a70dbf2">
  <property name="Cost" value="1ĄĄ" />
  <property name="CMC" value="3" />
  <property name="Color" value="White" />
  <property name="Type" value="Creature" />
  <property name="Subtype" value="Human Soldier" />
  <property name="Rarity" value="Uncommon" />
  <property name="Rules" value="Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Faithful Squire.&#xD;&#xA;At the beginning of the end step, if there are two or more ki counters on Faithful Squire, you may flip it." />
  <property name="Power" value="2" />
  <property name="Toughness" value="2" />
  <property name="PT Box" value="2 / 2" />
  <property name="Artist" value="Mark Zug" />
  <property name="MultiverseId" value="74093" />
  <alternate name="Kaiso, Memory of Loyalty" type="flip">
    <property name="Cost" value="1ĄĄ" />
    <property name="CMC" value="3" />
    <property name="Color" value="White" />
    <property name="Type" value="Legendary Creature" />
    <property name="Subtype" value="Spirit" />
    <property name="Rarity" value="Uncommon" />
    <property name="Rules" value="Flying&#xD;&#xA;Remove a ki counter from Kaiso, Memory of Loyalty: Prevent all damage that would be dealt to target creature this turn." />
    <property name="Power" value="3" />
    <property name="Toughness" value="4" />
    <property name="PT Box" value="3 / 4" />
    <property name="Artist" value="Mark Zug" />
    <property name="MultiverseId" value="74093" />
  </alternate>
</card>

顶级卡片对象的所有属性都是字段,所以我的目的是创建另一个屏蔽数组,其中包含“翻转”卡的属性,因此所有翻转卡都可以分类为(和属性)我可以创建这些属性的蒙版数组,并使用以下方法将其作为字段附加到较大的数组:

AllCards=numpy.lib.recfunctions.append_fields(AllCards,AlternateCardType,AlternateCard) 

但是当我尝试使用:

更新掩码时
AllCards.mask[AlternateCardType][0]=True

我收到以下错误:

Traceback (most recent call last):
    File "/Applications/Eclipse/plugins/org.python.pydev_2.7.3.2013031601/pysrc/pydevd.py", line 1397, in <module>
        debugger.run(setup['file'], None, None)
    File "/Applications/Eclipse/plugins/org.python.pydev_2.7.3.2013031601/pysrc/pydevd.py", line 1090, in run
        pydev_imports.execfile(file, globals, locals) #execute the script
    File "/Users/Andrew/Documents/Workspace/PyGather/PyGather.py", line 61, in <module>
        !AllCards.mask[AlternateCardType][0]=True
TypeError: expected a readable buffer object

在这个子掩码数组位于顶级数组之前,我能够像这样操作掩码,并且可以使用循环和赋值来掩盖我不想要的项目。我试图掩盖这一点,因为numpy.lib.recfunctions.append_fields自动将数据添加到数组中的第一项,我无法弄清楚如何适当填充数据。这是一个错误,还是我在代码中做错了什么!

Full Source

2 个答案:

答案 0 :(得分:0)

我建议不要将子阵列存储在导致问题的主要字段中,而是建议将翻转的卡片保存在自己的阵列中。从数据库组织的角度来考虑它;假设MultiverseId属性对于每张卡或卡+翻转组合是唯一的,您可以将其用作主要ID,可以说是在您的翻转阵列中。对于numpy记录数组而言,这可能不如在真正的关系数据库中那样有效;另外一个步骤可能是在主数组中有一个列来指示卡是否具有翻转方面以避免每次都检查子阵列,尽管这会使用更多的内存。

或者,您可以为翻转卡分配他们自己的唯一ID,并将它们存储在与常规卡相同的记录阵列中,因为属性似乎具有相同的名称,然后具有flip_id字段对于没有翻转方面的卡,可以设置一些设置值,例如0None,然后是那些有翻转卡的翻转卡的ID。 (翻转的卡可以在其flip_id字段中包含原始卡的ID,以将翻转的卡连接到原始卡/主卡。)

答案 1 :(得分:0)

我确实通过考虑我传递的内容来解决我的问题。子阵列的形状类似于(A,B,C,D ......)。你传递了一个掩码,它应该是相同的结构,所以我试图将True分配给一个元组。当我尝试使用(真,真,真......)时,它有效!