Skip to content

Commit

Permalink
Fix 1163
Browse files Browse the repository at this point in the history
Determine level column order based on digit in header (e.g., level008)
  • Loading branch information
MariusWirtz committed Oct 14, 2024
1 parent 4a5fed2 commit 826d9f1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
17 changes: 11 additions & 6 deletions TM1py/Services/HierarchyService.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,12 +488,20 @@ def update_or_create_hierarchy_from_dataframe(
# identify level columns
level_columns = []
level_weight_columns = []

# sort to assure right order of levels
for column in sorted(df.columns, reverse=True):
sorted_level_columns = sorted(
[col for col in df.columns if any(char.isdigit() for char in col)], # Filter columns with digits
key=lambda x: int(''.join(filter(str.isdigit, x))), # Sort based on numeric part
reverse=True # Descending order
)

# Process sorted columns
for column in sorted_level_columns:
if column.lower().startswith('level') and column[5:8].isdigit():
if len(column) == 8:
if len(column) == 8: # "LevelXXX"
level_columns.append(column)
elif len(column) == 15 and column.lower().endswith('_weight'):
elif len(column) == 15 and column.lower().endswith('_weight'): # "LevelXXX_weight"
level_weight_columns.append(column)

# case: no level weight columns. All weights are 1
Expand All @@ -503,9 +511,6 @@ def update_or_create_hierarchy_from_dataframe(
level_weight_columns.append(level_weight_column)
df[level_weight_column] = 1

if not len(level_columns) == len(level_weight_columns):
raise ValueError("Number of level columns must be equal to number of level weight columns")

if verify_edges:
self._validate_edges(df=df[[element_column, *level_columns]])

Expand Down
28 changes: 28 additions & 0 deletions Tests/HierarchyService_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from contextlib import suppress
from pathlib import Path

import pandas as pd
from mdxpy import MdxBuilder, MdxHierarchySet
from pandas import DataFrame

Expand Down Expand Up @@ -513,6 +514,33 @@ def test_update_or_create_hierarchy_from_dataframe(self):
hierarchy_name=self.region_dimension_name)
self._verify_region_dimension(hierarchy)

def test_update_or_create_hierarchy_from_dataframe_non_standard_level_order(self):
columns = [self.region_dimension_name, "ElementType", "Alias:a", "Currency:s", "population:n", "Level001",
"level000", "level001_weight", "level000_weight"]
data = [
['France', "Numeric", "Frankreich", "EUR", 60_000_000, "Europe", "World", 1, 1],
['Switzerland', 'Numeric', "Schweiz", "CHF", 9_000_000, "Europe", "World", 1, 1],
['Germany', 'Numeric', "Deutschland", "EUR", 84_000_000, "Europe", "World", 1, 1],
]
df = DataFrame(data=data, columns=columns)

df = pd.DataFrame(df[[self.region_dimension_name, "ElementType", "Alias:a", "Currency:s", "population:n", "level000",
"Level001", "level000_weight", "level001_weight"]])
print(df.to_markdown())
self.tm1.hierarchies.update_or_create_hierarchy_from_dataframe(
dimension_name=self.region_dimension_name,
hierarchy_name=self.region_dimension_name,
df=df,
element_column=self.region_dimension_name,
element_type_column="ElementType",
unwind=True
)

hierarchy = self.tm1.hierarchies.get(
dimension_name=self.region_dimension_name,
hierarchy_name=self.region_dimension_name)
self._verify_region_dimension(hierarchy)

def test_update_or_create_hierarchy_from_dataframe_existing_attributes(self):
columns = [self.region_dimension_name, "ElementType", "Currency:s", "population:n", "level001",
"level000", "level001_weight", "level000_weight"]
Expand Down

0 comments on commit 826d9f1

Please sign in to comment.