Note
Click here to download the full example code
Splitting and Partitioning Objects
Demonstrate splitting by mass and partitioning along dimensions.
import plotly
import pandas as pd
from functools import partial
from elphick.mass_composition.flowsheet import Flowsheet
from elphick.mass_composition.utils.partition import perfect
from elphick.mass_composition.datasets.sample_data import sample_data, size_by_assay
from elphick.mass_composition import MassComposition
# sphinx_gallery_thumbnail_number = -1
Create a mass-composition (mc) enabled Xarray Dataset
We get some demo data in the form of a pandas DataFrame
df_data: pd.DataFrame = sample_data()
df_data.head()
# Construct a MassComposition object and standardise the chemistry variables
obj_mc: MassComposition = MassComposition(df_data, name='test data')
print(obj_mc)
obj_mc.aggregate()
test data
<xarray.Dataset> Size: 216B
Dimensions: (index: 3)
Coordinates:
* index (index) int64 24B 0 1 2
Data variables:
mass_wet (index) float64 24B 100.0 90.0 110.0
mass_dry (index) float64 24B 90.0 80.0 90.0
H2O (index) float64 24B 10.0 11.11 18.18
Fe (index) float64 24B 57.0 59.0 61.0
SiO2 (index) float64 24B 5.2 3.1 2.2
Al2O3 (index) float64 24B 3.0 1.7 0.9
LOI (index) float64 24B 5.0 4.0 3.0
group (index) object 24B 'grp_1' 'grp_1' 'grp_2'
Attributes:
mc_name: test data
mc_vars_mass: ['mass_wet', 'mass_dry']
mc_vars_chem: ['Fe', 'SiO2', 'Al2O3', 'LOI']
mc_vars_attrs: ['group']
mc_interval_edges: {}
Split by Mass
Split the original Dataset by mass and return both the defined split and complement objects. Splitting with a float, splits mass but does not modify the absolute grade of the input.
obj_mc_split, obj_mc_comp = obj_mc.split(fraction=0.1)
print(obj_mc_split)
obj_mc_split.aggregate()
(0.1 * test data)
<xarray.Dataset> Size: 216B
Dimensions: (index: 3)
Coordinates:
* index (index) int64 24B 0 1 2
Data variables:
mass_wet (index) float64 24B 10.0 9.0 11.0
mass_dry (index) float64 24B 9.0 8.0 9.0
H2O (index) float64 24B 10.0 11.11 18.18
Fe (index) float64 24B 57.0 59.0 61.0
SiO2 (index) float64 24B 5.2 3.1 2.2
Al2O3 (index) float64 24B 3.0 1.7 0.9
LOI (index) float64 24B 5.0 4.0 3.0
group (index) object 24B 'grp_1' 'grp_1' 'grp_2'
Attributes:
mc_name: (0.1 * test data)
mc_vars_mass: ['mass_wet', 'mass_dry']
mc_vars_chem: ['Fe', 'SiO2', 'Al2O3', 'LOI']
mc_vars_attrs: ['group']
mc_interval_edges: {}
obj_mc_comp.aggregate()
Add the split and complement parts using the mc.add method
obj_mc_sum: MassComposition = obj_mc_split + obj_mc_comp
obj_mc_sum.aggregate()
Confirm the sum of the splits is materially equivalent to the starting object.
pd.testing.assert_frame_equal(obj_mc.data.to_dataframe(), obj_mc_sum.data.to_dataframe())
Partition by Dimension
In mineral processing, unit operations separate particles based on one (or more) property. Consider a sizing screen, separating by size. The characteristics of such separations can be defined by a function. The function is often called a partition curve or tromp curve.
First we load a size x assay dataset, with size fractions as the index. While the data is multidimensional (considering all assays), from the MassComposition object definition it is a 1D dataset (indexed by size).
df_data: pd.DataFrame = size_by_assay()
df_data
Create the object
mc_size: MassComposition = MassComposition(df_data, name='size sample')
print(mc_size)
mc_size.aggregate()
size sample
<xarray.Dataset> Size: 336B
Dimensions: (size: 6)
Coordinates:
* size (size) object 48B [0.85, 2.0) [0.5, 0.85) ... [0.0, 0.045)
Data variables:
mass_wet (size) float64 48B 3.3 9.9 26.5 2.5 8.8 49.0
mass_dry (size) float64 48B 3.3 9.9 26.5 2.5 8.8 49.0
H2O (size) float64 48B 0.0 0.0 0.0 0.0 0.0 0.0
Fe (size) float64 48B 64.15 64.33 64.52 62.65 62.81 55.95
SiO2 (size) float64 48B 2.04 2.05 1.84 2.88 2.12 6.39
Al2O3 (size) float64 48B 2.68 2.23 2.19 3.32 2.25 6.34
Attributes:
mc_name: size sample
mc_vars_mass: ['mass_wet', 'mass_dry']
mc_vars_chem: ['Fe', 'SiO2', 'Al2O3']
mc_vars_attrs: []
mc_interval_edges: {'size': {'left': 'retained', 'right': 'passing'}}
Visualise the data
fig = mc_size.plot_parallel(color='Fe')
fig
We partially initialise the perfect partition function The dim argument is added to inform the split method which dimension to apply the function/split to
partition = partial(perfect, d50=0.150, dim='size')
Separate the object using the defined partition
mc_coarse, mc_fine = mc_size.split_by_partition(partition_definition=partition)
mc_coarse.name = 'coarse'
mc_fine.name = 'fine'
fs: Flowsheet = Flowsheet().from_streams([mc_size, mc_coarse, mc_fine])
fig = fs.plot_network()
fig.show()
fig = fs.table_plot(table_pos='top',
sankey_color_var='Fe', sankey_edge_colormap='copper_r', sankey_vmin=50, sankey_vmax=70)
# noinspection PyTypeChecker
plotly.io.show(fig) # this call to show will set the thumbnail for use in the gallery
Total running time of the script: ( 0 minutes 0.849 seconds)