{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":112509,"databundleVersionId":14254895,"sourceType":"competition"}],"dockerImageVersionId":31192,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:49.038617Z","iopub.execute_input":"2026-01-17T09:57:49.039387Z","iopub.status.idle":"2026-01-17T09:57:49.851142Z","shell.execute_reply.started":"2026-01-17T09:57:49.039352Z","shell.execute_reply":"2026-01-17T09:57:49.850296Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import seaborn as sns\nimport matplotlib.pyplot as plt\nfrom matplotlib.lines import Line2D\nfrom torch.utils.data import Dataset\nfrom PIL import Image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:49.852651Z","iopub.execute_input":"2026-01-17T09:57:49.853293Z","iopub.status.idle":"2026-01-17T09:57:57.452835Z","shell.execute_reply.started":"2026-01-17T09:57:49.853272Z","shell.execute_reply":"2026-01-17T09:57:57.452185Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.palplot(sns.color_palette(\"bright\", 10))\npalette = sns.color_palette(\"bright\", 10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.453750Z","iopub.execute_input":"2026-01-17T09:57:57.454243Z","iopub.status.idle":"2026-01-17T09:57:57.633932Z","shell.execute_reply.started":"2026-01-17T09:57:57.454216Z","shell.execute_reply":"2026-01-17T09:57:57.633320Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/csiro-biomass/train.csv')\ntest = pd.read_csv('/kaggle/input/csiro-biomass/test.csv')\nsample  = pd.read_csv('/kaggle/input/csiro-biomass/test.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.634639Z","iopub.execute_input":"2026-01-17T09:57:57.634915Z","iopub.status.idle":"2026-01-17T09:57:57.674264Z","shell.execute_reply.started":"2026-01-17T09:57:57.634893Z","shell.execute_reply":"2026-01-17T09:57:57.673646Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.676987Z","iopub.execute_input":"2026-01-17T09:57:57.677311Z","iopub.status.idle":"2026-01-17T09:57:57.704464Z","shell.execute_reply.started":"2026-01-17T09:57:57.677292Z","shell.execute_reply":"2026-01-17T09:57:57.703936Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.705204Z","iopub.execute_input":"2026-01-17T09:57:57.705538Z","iopub.status.idle":"2026-01-17T09:57:57.716042Z","shell.execute_reply.started":"2026-01-17T09:57:57.705512Z","shell.execute_reply":"2026-01-17T09:57:57.715429Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.716972Z","iopub.execute_input":"2026-01-17T09:57:57.717207Z","iopub.status.idle":"2026-01-17T09:57:57.734462Z","shell.execute_reply.started":"2026-01-17T09:57:57.717191Z","shell.execute_reply":"2026-01-17T09:57:57.733760Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"col_only_in_train = [col for col in df.columns if col not in test.columns]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.735262Z","iopub.execute_input":"2026-01-17T09:57:57.735603Z","iopub.status.idle":"2026-01-17T09:57:57.748061Z","shell.execute_reply.started":"2026-01-17T09:57:57.735578Z","shell.execute_reply":"2026-01-17T09:57:57.747517Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(col_only_in_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.748770Z","iopub.execute_input":"2026-01-17T09:57:57.748955Z","iopub.status.idle":"2026-01-17T09:57:57.762420Z","shell.execute_reply.started":"2026-01-17T09:57:57.748941Z","shell.execute_reply":"2026-01-17T09:57:57.761903Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.groupby('image_path')['target_name'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.763253Z","iopub.execute_input":"2026-01-17T09:57:57.763877Z","iopub.status.idle":"2026-01-17T09:57:57.800643Z","shell.execute_reply.started":"2026-01-17T09:57:57.763855Z","shell.execute_reply":"2026-01-17T09:57:57.800102Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_new = df.pivot_table(\n    index=\"image_path\",\n    columns=\"target_name\",\n    values=\"target\",\n    aggfunc=\"first\"\n).reset_index()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.801251Z","iopub.execute_input":"2026-01-17T09:57:57.801512Z","iopub.status.idle":"2026-01-17T09:57:57.827617Z","shell.execute_reply.started":"2026-01-17T09:57:57.801473Z","shell.execute_reply":"2026-01-17T09:57:57.827094Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_new.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.828182Z","iopub.execute_input":"2026-01-17T09:57:57.828414Z","iopub.status.idle":"2026-01-17T09:57:57.837624Z","shell.execute_reply.started":"2026-01-17T09:57:57.828388Z","shell.execute_reply":"2026-01-17T09:57:57.836890Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom sklearn.base import TransformerMixin\nfrom sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler\n\nclass Custom_Scaler(TransformerMixin):\n    def __init__(self, except_col=None, cols=None, strategy=\"MinMax\"):\n        super().__init__()\n        self.except_col = except_col if except_col else []\n        self.cols = cols if cols else []\n        self.strategy = strategy\n\n    def fit(self, df, y=None):\n        df = df.copy()\n\n        numerical_cols = df.select_dtypes(include=[np.number]).columns\n        final_col = numerical_cols.difference(self.except_col)\n        self.col = final_col if not self.cols else self.cols\n\n        if self.strategy == \"RBT\":\n            self.scaler = RobustScaler().fit(df[self.col])\n        elif self.strategy == \"STD\":\n            self.scaler = StandardScaler().fit(df[self.col])\n        else:\n            self.scaler = MinMaxScaler().fit(df[self.col])\n\n        return self\n\n    def transform(self, data, y=None):\n        df = data.copy()\n\n        scaled = self.scaler.transform(df[self.col])\n        scaled_df = pd.DataFrame(scaled, columns=self.col, index=df.index)\n\n        other_cols = df.columns.difference(self.col)\n\n        return pd.concat([scaled_df, df[other_cols]], axis=1)\n\n    def inverse_transform(self, data):\n        \"\"\"\n        Inverse scaling ONLY on scaled columns\n        \"\"\"\n        df = data.copy()\n\n        inv_scaled = self.scaler.inverse_transform(df[self.col])\n        inv_scaled_df = pd.DataFrame(inv_scaled, columns=self.col, index=df.index)\n\n        other_cols = df.columns.difference(self.col)\n\n        return pd.concat([inv_scaled_df, df[other_cols]], axis=1)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.838477Z","iopub.execute_input":"2026-01-17T09:57:57.838768Z","iopub.status.idle":"2026-01-17T09:57:57.960203Z","shell.execute_reply.started":"2026-01-17T09:57:57.838751Z","shell.execute_reply":"2026-01-17T09:57:57.959644Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"scaler = Custom_Scaler(cols=['Dry_Clover_g','Dry_Dead_g','Dry_Green_g','Dry_Total_g','GDM_g'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.963144Z","iopub.execute_input":"2026-01-17T09:57:57.963407Z","iopub.status.idle":"2026-01-17T09:57:57.966906Z","shell.execute_reply.started":"2026-01-17T09:57:57.963389Z","shell.execute_reply":"2026-01-17T09:57:57.966386Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_new = scaler.fit_transform(df_new)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.967669Z","iopub.execute_input":"2026-01-17T09:57:57.967873Z","iopub.status.idle":"2026-01-17T09:57:57.988410Z","shell.execute_reply.started":"2026-01-17T09:57:57.967852Z","shell.execute_reply":"2026-01-17T09:57:57.987616Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_new.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:57.989272Z","iopub.execute_input":"2026-01-17T09:57:57.989621Z","iopub.status.idle":"2026-01-17T09:57:58.009136Z","shell.execute_reply.started":"2026-01-17T09:57:57.989596Z","shell.execute_reply":"2026-01-17T09:57:58.008408Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class BiomassDataset(Dataset):\n    def __init__(self, df, transforms=None):\n        self.df = df\n        self.transforms = transforms\n\n        self.target_cols = [\n            \"Dry_Clover_g\",\n            \"Dry_Dead_g\",\n            \"Dry_Green_g\",\n            \"Dry_Total_g\",\n            \"GDM_g\"\n        ]\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n\n        # Image\n        image = Image.open('/kaggle/input/csiro-biomass/'+ row[\"image_path\"]).convert(\"RGB\")\n        if self.transforms:\n            image = self.transforms(image)\n\n        # Targets : conversion garantie float\n        targets = torch.tensor(\n            row[self.target_cols].astype(float).values,\n            dtype=torch.float32\n        )\n\n        return image, targets\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:58.009947Z","iopub.execute_input":"2026-01-17T09:57:58.010272Z","iopub.status.idle":"2026-01-17T09:57:58.138195Z","shell.execute_reply.started":"2026-01-17T09:57:58.010247Z","shell.execute_reply":"2026-01-17T09:57:58.137626Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch.nn as nn\nfrom torchvision import models\n\nclass ConvNeXtMultiOutput(nn.Module):\n    def __init__(self, num_outputs=5, pretrained=True):\n        super().__init__()\n\n        # Load ConvNeXt Tiny\n        self.backbone = models.convnext_tiny(\n            weights=models.ConvNeXt_Tiny_Weights.DEFAULT if pretrained else None\n        )\n\n        in_features = self.backbone.classifier[2].in_features\n        self.backbone.classifier = nn.Sequential(\n            nn.Flatten(),\n            nn.Linear(in_features, 512),\n            nn.ReLU(),\n            nn.Dropout(0.3),\n            nn.Linear(512, num_outputs)\n        )\n\n    def forward(self, x):\n        return self.backbone(x)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:57:58.139016Z","iopub.execute_input":"2026-01-17T09:57:58.139305Z","iopub.status.idle":"2026-01-17T09:58:02.592224Z","shell.execute_reply.started":"2026-01-17T09:57:58.139248Z","shell.execute_reply":"2026-01-17T09:58:02.591552Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torchvision import transforms\n\ntrain_transforms = transforms.Compose([\n    transforms.Resize(1024),             # resize le plus petit côté à 1024 (ratio conservé)\n    transforms.CenterCrop((1024, 512)),  # on garde un crop proportionnel (ratio ~2:1)\n    transforms.RandomResizedCrop(\n        224,\n        scale=(0.7, 1.0),\n        ratio=(1.8/1.0, 2.2/1.0)         # ratio stable autour de 2:1\n    ),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n    transforms.Normalize(\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]\n    ),\n])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:58:02.593093Z","iopub.execute_input":"2026-01-17T09:58:02.593519Z","iopub.status.idle":"2026-01-17T09:58:02.598924Z","shell.execute_reply.started":"2026-01-17T09:58:02.593497Z","shell.execute_reply":"2026-01-17T09:58:02.598094Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"val_transforms = transforms.Compose([\n    transforms.Resize(1024),\n    transforms.CenterCrop((1024, 512)),\n    transforms.Resize(224),  # on réduit proprement après avoir respecté le ratio\n    transforms.CenterCrop(224),\n    transforms.ToTensor(),\n    transforms.Normalize(\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]\n    ),\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:58:02.599881Z","iopub.execute_input":"2026-01-17T09:58:02.600203Z","iopub.status.idle":"2026-01-17T09:58:02.627525Z","shell.execute_reply.started":"2026-01-17T09:58:02.600177Z","shell.execute_reply":"2026-01-17T09:58:02.626940Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\n\ntrain_dataset = BiomassDataset(df_new, transforms=train_transforms)\ntrain_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)\n\nmodel = ConvNeXtMultiOutput(num_outputs=5, pretrained=False).to(\"cuda\")\n\ncriterion = nn.MSELoss()\noptimizer = optim.AdamW(model.parameters(), lr=1e-4)\n\nfor epoch in range(10):\n    model.train()\n    total_loss = 0\n\n    for images, targets in train_loader:\n        images = images.to(\"cuda\")\n        targets = targets.to(\"cuda\")\n\n        preds = model(images)\n        loss = criterion(preds, targets)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n\n    print(f\"Epoch {epoch+1} - Loss: {total_loss/len(train_loader):.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T09:58:02.628450Z","iopub.execute_input":"2026-01-17T09:58:02.628759Z","iopub.status.idle":"2026-01-17T10:04:16.027193Z","shell.execute_reply.started":"2026-01-17T09:58:02.628729Z","shell.execute_reply":"2026-01-17T10:04:16.026536Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test.head(1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.028009Z","iopub.execute_input":"2026-01-17T10:04:16.028234Z","iopub.status.idle":"2026-01-17T10:04:16.036018Z","shell.execute_reply.started":"2026-01-17T10:04:16.028217Z","shell.execute_reply":"2026-01-17T10:04:16.035307Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class BiomassTestDataset(Dataset):\n    def __init__(self, df, transforms=None):\n        self.df = df\n        self.transforms = transforms\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n\n        # Charger l'image\n        image = Image.open('/kaggle/input/csiro-biomass/'+ row[\"image_path\"]).convert(\"RGB\")\n        if self.transforms:\n            image = self.transforms(image)\n\n        return image, row[\"image_path\"]  # on garde image_path pour soumission\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.036723Z","iopub.execute_input":"2026-01-17T10:04:16.036973Z","iopub.status.idle":"2026-01-17T10:04:16.050595Z","shell.execute_reply.started":"2026-01-17T10:04:16.036956Z","shell.execute_reply":"2026-01-17T10:04:16.049924Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_transforms = transforms.Compose([\n    transforms.Resize(1024),\n    transforms.CenterCrop((1024, 512)),\n    transforms.Resize(224),\n    transforms.CenterCrop(224),\n    transforms.ToTensor(),\n    transforms.Normalize(\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]\n    ),\n])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.051380Z","iopub.execute_input":"2026-01-17T10:04:16.051696Z","iopub.status.idle":"2026-01-17T10:04:16.068920Z","shell.execute_reply.started":"2026-01-17T10:04:16.051676Z","shell.execute_reply":"2026-01-17T10:04:16.068224Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_dataset = BiomassTestDataset(test.head(1) , transforms=test_transforms)\ntest_loader = DataLoader(test_dataset, batch_size=16, shuffle=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.069778Z","iopub.execute_input":"2026-01-17T10:04:16.070000Z","iopub.status.idle":"2026-01-17T10:04:16.082229Z","shell.execute_reply.started":"2026-01-17T10:04:16.069978Z","shell.execute_reply":"2026-01-17T10:04:16.081709Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\npredictions = []\n\nwith torch.no_grad():\n    for images, image_paths in test_loader:\n        images = images.to(\"cuda\")\n        preds = model(images)  # shape [batch_size, 5]\n\n        preds = preds.cpu().numpy()\n        for path, pred in zip(image_paths, preds):\n            predictions.append((path, pred))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.082910Z","iopub.execute_input":"2026-01-17T10:04:16.083103Z","iopub.status.idle":"2026-01-17T10:04:16.278262Z","shell.execute_reply.started":"2026-01-17T10:04:16.083089Z","shell.execute_reply":"2026-01-17T10:04:16.277677Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.279046Z","iopub.execute_input":"2026-01-17T10:04:16.279321Z","iopub.status.idle":"2026-01-17T10:04:16.284524Z","shell.execute_reply.started":"2026-01-17T10:04:16.279293Z","shell.execute_reply":"2026-01-17T10:04:16.283768Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pd.DataFrame({\n    \"image_path\" : predictions[0][0],\n    \"Dry_Clover_g\":predictions[0][1][0] ,\n    \"Dry_Dead_g\":predictions[0][1][1],\n    \"Dry_Green_g\":predictions[0][1][2],\n    \"Dry_Total_g\":predictions[0][1][3],\n    \"GDM_g\":predictions[0][1][4]\n}, index=[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.285258Z","iopub.execute_input":"2026-01-17T10:04:16.285510Z","iopub.status.idle":"2026-01-17T10:04:16.307322Z","shell.execute_reply.started":"2026-01-17T10:04:16.285469Z","shell.execute_reply":"2026-01-17T10:04:16.306681Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"scaler.inverse_transform(pd.DataFrame({\n    \"image_path\" : predictions[0][0],\n    \"Dry_Clover_g\":predictions[0][1][0] ,\n    \"Dry_Dead_g\":predictions[0][1][1],\n    \"Dry_Green_g\":predictions[0][1][2],\n    \"Dry_Total_g\":predictions[0][1][3],\n    \"GDM_g\":predictions[0][1][4]\n}, index=[0]))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.308640Z","iopub.execute_input":"2026-01-17T10:04:16.308885Z","iopub.status.idle":"2026-01-17T10:04:16.329705Z","shell.execute_reply.started":"2026-01-17T10:04:16.308869Z","shell.execute_reply":"2026-01-17T10:04:16.328929Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission =  scaler.inverse_transform(pd.DataFrame({\n    \"image_path\" : predictions[0][0],\n    \"Dry_Clover_g\":predictions[0][1][0] ,\n    \"Dry_Dead_g\":predictions[0][1][1],\n    \"Dry_Green_g\":predictions[0][1][2],\n    \"Dry_Total_g\":predictions[0][1][3],\n    \"GDM_g\":predictions[0][1][4],\n    'id' :  test['sample_id'].apply(lambda x : x.split('__')[0])\n}, index=[0]))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.330527Z","iopub.execute_input":"2026-01-17T10:04:16.330833Z","iopub.status.idle":"2026-01-17T10:04:16.351695Z","shell.execute_reply.started":"2026-01-17T10:04:16.330804Z","shell.execute_reply":"2026-01-17T10:04:16.351131Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.352326Z","iopub.execute_input":"2026-01-17T10:04:16.352563Z","iopub.status.idle":"2026-01-17T10:04:16.376524Z","shell.execute_reply.started":"2026-01-17T10:04:16.352538Z","shell.execute_reply":"2026-01-17T10:04:16.375877Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\nTARGET_COLS = [\n    \"Dry_Clover_g\",\n    \"Dry_Dead_g\",\n    \"Dry_Green_g\",\n    \"Dry_Total_g\",\n    \"GDM_g\"\n]\n\n# df = ton DataFrame actuel\n\n# 1. Passer en format long\nsubmission = submission.melt(\n    id_vars=[\"id\"],\n    value_vars=TARGET_COLS,\n    var_name=\"target_name\",\n    value_name=\"target\"\n)\n\n# 2. Construire sample_id\nsubmission[\"sample_id\"] = (\n    submission[\"id\"] + \"__\" + submission[\"target_name\"]\n)\n\n# 3. Garder UNIQUEMENT les colonnes attendues\nsubmission = submission[[\"sample_id\", \"target\"]]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.377248Z","iopub.execute_input":"2026-01-17T10:04:16.378085Z","iopub.status.idle":"2026-01-17T10:04:16.394801Z","shell.execute_reply.started":"2026-01-17T10:04:16.378066Z","shell.execute_reply":"2026-01-17T10:04:16.394001Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.395546Z","iopub.execute_input":"2026-01-17T10:04:16.395793Z","iopub.status.idle":"2026-01-17T10:04:16.411782Z","shell.execute_reply.started":"2026-01-17T10:04:16.395771Z","shell.execute_reply":"2026-01-17T10:04:16.411115Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission[\"target\"] = submission[\"target\"].clip(lower=0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.412473Z","iopub.execute_input":"2026-01-17T10:04:16.412783Z","iopub.status.idle":"2026-01-17T10:04:16.425657Z","shell.execute_reply.started":"2026-01-17T10:04:16.412756Z","shell.execute_reply":"2026-01-17T10:04:16.425047Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-17T10:04:16.426390Z","iopub.execute_input":"2026-01-17T10:04:16.426684Z","iopub.status.idle":"2026-01-17T10:04:16.444733Z","shell.execute_reply.started":"2026-01-17T10:04:16.426664Z","shell.execute_reply":"2026-01-17T10:04:16.443984Z"}},"outputs":[],"execution_count":null}]}