legacy structure (I hope)

This commit is contained in:
Jan Kieseler
2025-10-16 15:11:50 +02:00
parent 589b50522b
commit cc41ed3c65
2 changed files with 52 additions and 8 deletions
+11 -7
View File
@@ -144,19 +144,23 @@ class MiniFrame:
def copy(self) -> "MiniFrame": def copy(self) -> "MiniFrame":
return MiniFrame({k: v.copy() for k, v in self._data.items()}) return MiniFrame({k: v.copy() for k, v in self._data.items()})
def to_pandas(self): def to_pandas(self, indiv_cols: bool = True):
import pandas as pd import pandas as pd
df = pd.DataFrame() out = {}
for k, v in self._data.items(): for k, v in self._data.items():
if v.ndim == 1: if v.ndim == 1:
df[k] = v out[k] = v # 1D numeric column
elif v.ndim == 2: elif v.ndim == 2 and indiv_cols:
# expand fixed-size vectors into wide columns # expand into wide columns
for i in range(v.shape[1]): for i in range(v.shape[1]):
df[f"{k}_{i}"] = v[:, i] out[f"{k}_{i}"] = v[:, i]
elif v.ndim == 2 and not indiv_cols:
# legacy nested: one Python list per row (object dtype)
# NOTE: v.tolist() -> List[List[...]] which most legacy code expects
out[k] = pd.Series(v.tolist(), dtype=object)
else: else:
raise ValueError(f"Column '{k}' has ndim={v.ndim}, not supported.") raise ValueError(f"Column '{k}' has ndim={v.ndim}, not supported.")
return df return pd.DataFrame(out)
# convenience constructor # convenience constructor
@staticmethod @staticmethod
+41 -1
View File
@@ -49,4 +49,44 @@ print("\n=== Describe ===")
desc = mf_all.describe() desc = mf_all.describe()
print(desc) print(desc)
print("\nAll basic minipandas features appear to work correctly.") print("\nAll basic minipandas features appear to work correctly.")
# --- Create a simple MiniFrame ---
N, M = 3, 4
mf = mpd.MiniFrame({
"run": 1, # scalar -> broadcast
"event": np.arange(N), # 1D scalar column
"energy": np.arange(N * M).reshape(N, M), # 2D vector column
})
# --- Case 1: indiv_cols=True (default) ---
df_wide = mf.to_pandas(indiv_cols=True)
print("=== Expanded columns ===")
print(df_wide)
# Expected shape: N rows, 1 scalar column ('event'), 1 broadcasted column ('run'), and M expanded columns
assert list(df_wide.columns) == ["run", "event"] + [f"energy_{i}" for i in range(M)]
assert df_wide.shape == (N, 2 + M)
assert np.allclose(df_wide["energy_0"], [0, 4, 8])
# --- Case 2: indiv_cols=False (legacy nested format) ---
df_nested = mf.to_pandas(indiv_cols=False)
print("\n=== Nested legacy format ===")
print(df_nested)
# Expected columns: run, event, energy
assert list(df_nested.columns) == ["run", "event", "energy"]
assert isinstance(df_nested.loc[0, "energy"], list)
assert df_nested.loc[0, "energy"] == [0, 1, 2, 3]
# --- Round-trip compatibility check ---
mf2 = mpd.MiniFrame({
"run": df_nested["run"].to_numpy(),
"event": df_nested["event"].to_numpy(),
"energy": np.stack(df_nested["energy"].to_numpy()),
})
assert np.allclose(mf["energy"], mf2["energy"])
print("\n✅ All checks passed successfully!")