|
13 | 13 | from collections.abc import Callable, Collection, Iterable, Sequence |
14 | 14 | from typing import Any |
15 | 15 |
|
| 16 | +import numpy as np |
16 | 17 | import pandas as pd |
17 | 18 |
|
18 | 19 | from nsight import annotation, exceptions, thermovision, transformation, utils |
@@ -435,6 +436,10 @@ def wrapper( |
435 | 436 | self.settings.output_progress, |
436 | 437 | ) |
437 | 438 |
|
| 439 | + # Explode the dataframe. |
| 440 | + raw_df = self._explode_dataframe(raw_df) |
| 441 | + processed = self._explode_dataframe(processed) |
| 442 | + |
438 | 443 | # Save to CSV if enabled |
439 | 444 | if self.settings.output_csv: |
440 | 445 | raw_csv_path = ( |
@@ -468,3 +473,42 @@ def wrapper( |
468 | 473 | return None |
469 | 474 |
|
470 | 475 | return wrapper |
| 476 | + |
| 477 | + def _explode_dataframe(self, df: pd.DataFrame) -> pd.DataFrame: |
| 478 | + """ |
| 479 | + Explode columns with list/tuple/np.ndarray values into multiple rows. |
| 480 | +
|
| 481 | + Two scenarios: |
| 482 | + 1. No derived metrics (all "Transformed" = False): |
| 483 | + - All columns maybe contain multiple values (lists/arrays). |
| 484 | + - Use `explode()` to flatten each list element into separate rows. |
| 485 | + 2. With derived metrics: |
| 486 | + - Metric columns contain either: |
| 487 | + a) Single-element lists (from derived metrics) - extract the scalar |
| 488 | + b) Scalars (from original metrics) - keep as-is |
| 489 | + - Only flatten single-element lists to scalars, don't create new rows. |
| 490 | +
|
| 491 | + Args: |
| 492 | + df: Dataframe to be exploded. |
| 493 | +
|
| 494 | + Returns: |
| 495 | + Exploded dataframe. |
| 496 | + """ |
| 497 | + df_explode = None |
| 498 | + if df["Transformed"].eq(False).all(): |
| 499 | + # 1: No derived metrics - explode all columns with sequences into rows. |
| 500 | + df_explode = df.apply(pd.Series.explode).reset_index(drop=True) |
| 501 | + else: |
| 502 | + # 2: With derived metrics - only explode columns with single-value sequences. |
| 503 | + df_explode = df.apply( |
| 504 | + lambda col: ( |
| 505 | + col.apply( |
| 506 | + lambda x: ( |
| 507 | + x[0] |
| 508 | + if isinstance(x, (list, tuple, np.ndarray)) and len(x) == 1 |
| 509 | + else x |
| 510 | + ) |
| 511 | + ) |
| 512 | + ) |
| 513 | + ) |
| 514 | + return df_explode |
0 commit comments