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
.indexand.columns, this can break the DataFrame logic, as, in the above example,mfrwas 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!