Skip to content

MetaFrames (mfr/mfc)

View

The MetaFrames (DataFrame view of a DataFrame index/columns) are accessible via the mfr (MetaFrameRow) and mfc (MetaFrameCol) properties:

>>> df.index
MultiIndex([('a', 1, 1.1, False, 2024-01-01, nan, 0, 'x', 10.0, 1.5, ...),
            ('b', 2, 2.2, False, 2024-01-02, nan, 0, nan,  nan, 2.5, ...),
            ('c', 3, 3.3,  True, 2024-01-03, nan, 2, 'y', 12.0, nan, ...),
            ('d', 4, 4.4,  True, 2024-01-04, nan, 1, 'z',  nan, 4.5, ...),
            ('e', 5, 5.5, False, 2024-01-05, nan, 2, nan, 14.0, nan, ...)],
           names=['strings', 'integers', 'floats', 'bool', 'dates', 'none_values', 'group', 'strings_with_missing', 'ints_with_missing', 'floats_with_missing', 'bool_with_missing', 'dates_with_missing', 'mixed_numeric', 'mixed_types'])
>>> df.mfr
    strings  integers  floats   bool  ... bool_with_missing  dates_with_missing  mixed_numeric mixed_types
                                      ...                                                                 
0         a         1     1.1  False  ...             False          2024-02-01              1           1
1         b         2     2.2  False  ...               NaN                 NaN            2.2           a
2         c         3     3.3   True  ...               NaN          2024-02-03              3        3.14
3         d         4     4.4   True  ...              True                 NaN            4.4         NaN
4         e         5     5.5  False  ...               NaN          2024-02-05            NaN  2024-03-01

[5 rows x 14 columns]
>>> df.columns
MultiIndex([('f', 1, nan, 1),
            ('g', 2, nan, 0),
            ('h', 3, nan, 1),
            ('i', 4, nan, 3)],
           names=['strings', 'id', 'none_values', 'group'])
>>> df.mfc
    strings  id  none_values  group

0         f   1          NaN      1
1         g   2          NaN      0
2         h   3          NaN      1
3         i   4          NaN      3

Simple pd.Index index/columns also have their respective MetaFrame view:

>>> table.columns
Index(['strings', 'integers', 'floats', 'bool', 'dates', 'none_values',
       'group', 'strings_with_missing', 'ints_with_missing',
       'floats_with_missing', 'bool_with_missing', 'dates_with_missing',
       'mixed_numeric', 'mixed_types'],
      dtype='str')
>>> table.mfc
                        0

0                 strings
1                integers
2                  floats
3                    bool
4                   dates
5             none_values
6                   group
7    strings_with_missing
8       ints_with_missing
9     floats_with_missing
10      bool_with_missing
11     dates_with_missing
12          mixed_numeric
13            mixed_types

Write

Like .index and .columns, MetaFrames properties are writable, in two ways:

From a MetaFrame-like DataFrame

Any DataFrame complying to MetaFrame format restrictions (simple index/columns + numeric index) can be set to .mfr and .mfc:

>>> dataframe
strings             f  g     h
group               1  0     1
floats bool  group            
1.1    False 0      1  A     2
2.2    False 0      2  B  None
3.3    True  2      3  C     B
4.4    True  1      4  D  None
>>> dataframe.mfr
     floats   bool  group

0       1.1  False      0
1       2.2  False      0
2       3.3   True      2
3       4.4   True      1
>>> new_mfr = dataframe.mf(axis=0)[::-1]
>>> new_mfr
   floats   bool  group
3     4.4   True      1
2     3.3   True      2
1     2.2  False      0
0     1.1  False      0
>>> dataframe.mfr = new_mfr
>>> dataframe
strings             f  g     h
group               1  0     1
floats bool  group            
4.4    True  1      1  A     2
3.3    True  2      2  B  None
2.2    False 0      3  C     B
1.1    False 0      4  D  None

Notice that, like .index and .columns, this can break the DataFrame logic, as, in the above example, mfr was reversed but the DataFrame matrix stayed unaffected.

From a _MetaFrame object

A _MetaFrame is the object returned by the .mfr and .mfc properties:

>>> type(dataframe.mfr)
<class 'metaframe.src.metaframe.base._MetaFrame'>

This object keep tracks of the Metaframe rows it originated throughout its life-time:

>>> dataframe
strings             f  g     h
group               1  0     1
floats bool  group            
1.1    False 0      1  A     2
2.2    False 0      2  B  None
3.3    True  2      3  C     B
4.4    True  1      4  D  None
>>> dataframe.mfr
     floats   bool  group

0       1.1  False      0
1       2.2  False      0
2       3.3   True      2
3       4.4   True      1
>>> dataframe.mfr = dataframe.mfr[::-1]
>>> dataframe
strings             f  g     h
group               1  0     1
floats bool  group            
4.4    True  1      4  D  None
3.3    True  2      3  C     B
2.2    False 0      2  B  None
1.1    False 0      1  A     2

Notice that the DataFrame matrix was also reversed

If an operation cause the _MetaFrame object to lose the its original MetaFrame row tracking, a message will indicate that the _MetaSet is broken, and an error will be raised when trying to set it to the MetaFrame:

>>> mfr = dataframe.mfr
>>> mfr = mfr.reset_index()
Broken MetaFrame (source: reset_index): Index was reseted and may not correspond to DataFrame row numbers!
>>> dataframe.mfr = mfr
ValueError: Broken MetaFrame (source: reset_index): Index was reseted and may not correspond to DataFrame row numbers!

An other restriction is that the MetaFrame should not be modified after the _MetaFrame creation:

>>> mfr = dataframe.mfr
>>> dataframe.mfr = dataframe.mfr[::-1]
>>> dataframe.mfr = mfr
ValueError: Can not set a MetaFrame with an object generated before the MetaFrame latest modification!