Does numpy.ma allow masking of sub-masked arrays in a masked array?
Question: I am writing some code in Python 2.7 (using pydev in eclipse, Mac OSX) to
gather information about a big set of card information stored in xml files.
The cards are from Magic the gathering and all have a very similar card
structure (Name, cost to play, type, etc.)

I am using masked arrays to store all of the information on the cards. Here is
the array I initialize to store this information (more fields are added as
they are encountered in the code):

    
    
    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')])
    

I have been able to populate and mask this array as I wanted, but I am running
into a particular problem when I start to make this original array more
complicated. When a card such as [Faithful
Squire](http://gatherer.wizards.com/pages/card/Details.aspx?multiverseid=74093),
which has more complex components than a regular card (the flip aspect), it is
coded in the xml as:

    
    
    <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>
    

All of the propertys of the top-level card object are the fields, so my
intention is to create another masked array that holds the properties of
"flip" cards, so all the flip cards can be categorized as such (and properties
analyzed, etc.) I am able to create a masked array of these properties, and
append it as a field to the larger array using:

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

but when I try to update the mask using:

    
    
    AllCards.mask[AlternateCardType][0]=True
    

I receive the following error:

    
    
    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
    

before this sub masked array is in the top-level array, I am able to
manipulate the mask as such, and can use loops and assignments to mask items I
don't want. I am trying to mask this because
numpy.lib.recfunctions.append_fields automatically adds the data to the first
item in the array, and I couldn't figure out how to pad the data
appropriately. Is this a bug, or am I doing something wrong in the code!

[Full Source](https://www.dropbox.com/s/todaqrlalhhl4s2/PyGather.txt)


Answer: Rather than storing the subarrays in fields of the main one, which is causing
you problems, I'd recommend keeping the flipped cards in their own array.
Think of it in terms of database organization; assuming the `MultiverseId`
attribute is unique to each card or card+flip combo, you can use that as the
primary ID, so to speak, in your flip array. That may not be as efficient with
numpy record arrays as it would in a true relational database, though; an
additional step may be to have a column in the main array to indicate whether
or not the card has a flip aspect to avoid having to check the subarray each
time, though that would use a bit more memory.

Alternatively, you could assign the flip cards their own unique IDs and store
them in the same record array as the regular cards, as the properties seem to
have the same names, and then have a `flip_id` field that would be some set
value such as `0` or `None` for cards without flip aspects and then the ID of
the flip card for those cards that do have a flip. (The flipped card could
then have the original card's ID in its `flip_id` field to connect the flipped
card to the original/main one.)

