Spaces:
Sleeping
Sleeping
Download src/potatopheno/aggregation.py from pcisdeli/TuberVision: direct link, hf CLI and curl.
- Browser
- Download file 1.88 kB
-
https://huggingface.co/spaces/pcisdeli/TuberVision/resolve/main/src/potatopheno/aggregation.py
- Command line
-
hf download hf://spaces/pcisdeli/TuberVision/src/potatopheno/aggregation.py
-
curl -L -o aggregation.py https://huggingface.co/spaces/pcisdeli/TuberVision/resolve/main/src/potatopheno/aggregation.py
1.88 kB
| """Plot-level aggregation of per-tuber morphometrics. | |
| Per (trial, Plot_std): total projected area and tuber count. | |
| Per (trial, Plot_std, class): class-specific projected area, pivoted | |
| wide to area_{B,A1,A2,OV}_in2 with NaN replaced by 0 for absent classes. | |
| """ | |
| from __future__ import annotations | |
| import pandas as pd | |
| CLASS_AREA_COLUMNS: tuple[str, ...] = ( | |
| "area_B_in2", | |
| "area_A1_in2", | |
| "area_A2_in2", | |
| "area_OV_in2", | |
| ) | |
| def aggregate_total_area(df: pd.DataFrame) -> pd.DataFrame: | |
| """One row per (trial, Plot_std) with total_area_in2 and n_tubers.""" | |
| return ( | |
| df.groupby(["trial", "Plot_std"], as_index=False) | |
| .agg( | |
| total_area_in2=("area_poly_in2", "sum"), | |
| n_tubers=("detection_id", "count"), | |
| ) | |
| ) | |
| def aggregate_area_by_class_wide(df: pd.DataFrame) -> pd.DataFrame: | |
| """One row per (trial, Plot_std) with one column per USDA class area.""" | |
| long = ( | |
| df.groupby(["trial", "Plot_std", "class"], as_index=False, observed=True) | |
| .agg(class_area_in2=("area_poly_in2", "sum")) | |
| ) | |
| wide = ( | |
| long.pivot(index=["trial", "Plot_std"], columns="class", values="class_area_in2") | |
| .fillna(0) | |
| .reset_index() | |
| .rename( | |
| columns={ | |
| "B": "area_B_in2", | |
| "A1": "area_A1_in2", | |
| "A2": "area_A2_in2", | |
| "OV": "area_OV_in2", | |
| } | |
| ) | |
| ) | |
| wide.columns.name = None | |
| for col in CLASS_AREA_COLUMNS: | |
| if col not in wide.columns: | |
| wide[col] = 0.0 | |
| return wide | |
| def aggregate_by_plot(df: pd.DataFrame) -> pd.DataFrame: | |
| """Combine total-area and class-area-wide aggregations on (trial, Plot_std).""" | |
| df_total = aggregate_total_area(df) | |
| df_wide = aggregate_area_by_class_wide(df) | |
| return df_total.merge(df_wide, on=["trial", "Plot_std"], how="left") | |