{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# How to make a submission using the Run-Length Encoding format","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\n\nfrom pathlib import Path\ndata_path = Path('/kaggle/input/google-research-identify-contrails-reduce-global-warming')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-05-06T11:37:48.925782Z","iopub.execute_input":"2023-05-06T11:37:48.926862Z","iopub.status.idle":"2023-05-06T11:37:48.956957Z","shell.execute_reply.started":"2023-05-06T11:37:48.92681Z","shell.execute_reply":"2023-05-06T11:37:48.956012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Run-Length Code\n\nThe following is code to both encode and decode RLE format.\n\nIMPORTANT: Unlike many previous Kaggle competition, empty predictions must be encoded as `'-'`. Empty string / null predictions will cause an error in scoring. The code below handles this change.","metadata":{}},{"cell_type":"code","source":"def rle_encode(x, fg_val=1):\n    \"\"\"\n    Args:\n        x:  numpy array of shape (height, width), 1 - mask, 0 - background\n    Returns: run length encoding as list\n    \"\"\"\n\n    dots = np.where(\n        x.T.flatten() == fg_val)[0]  # .T sets Fortran order down-then-right\n    run_lengths = []\n    prev = -2\n    for b in dots:\n        if b > prev + 1:\n            run_lengths.extend((b + 1, 0))\n        run_lengths[-1] += 1\n        prev = b\n    return run_lengths\n\n\ndef list_to_string(x):\n    \"\"\"\n    Converts list to a string representation\n    Empty list returns '-'\n    \"\"\"\n    if x: # non-empty list\n        s = str(x).replace(\"[\", \"\").replace(\"]\", \"\").replace(\",\", \"\")\n    else:\n        s = '-'\n    return s\n\n\ndef rle_decode(mask_rle, shape=(256, 256)):\n    '''\n    mask_rle: run-length as string formatted (start length)\n              empty predictions need to be encoded with '-'\n    shape: (height, width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n    '''\n\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    if mask_rle != '-': \n        s = mask_rle.split()\n        starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n        starts -= 1\n        ends = starts + lengths\n        for lo, hi in zip(starts, ends):\n            img[lo:hi] = 1\n    return img.reshape(shape, order='F')  # Needed to align to RLE direction","metadata":{"execution":{"iopub.status.busy":"2023-05-06T11:42:57.060077Z","iopub.execute_input":"2023-05-06T11:42:57.061183Z","iopub.status.idle":"2023-05-06T11:42:57.073457Z","shell.execute_reply.started":"2023-05-06T11:42:57.061133Z","shell.execute_reply":"2023-05-06T11:42:57.072652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Create a naive submission\n\nWe'll use just `band_08` and predict that the 1000 pixels with the highest numerical values are contrails.","metadata":{}},{"cell_type":"code","source":"test_recs = os.listdir(data_path / 'test')\nprint(test_recs)","metadata":{"execution":{"iopub.status.busy":"2023-05-06T11:42:59.061452Z","iopub.execute_input":"2023-05-06T11:42:59.062351Z","iopub.status.idle":"2023-05-06T11:42:59.075815Z","shell.execute_reply.started":"2023-05-06T11:42:59.062311Z","shell.execute_reply":"2023-05-06T11:42:59.074848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n = 1000\nband_08 = np.load(data_path / 'test' / test_recs[0] / 'band_08.npy').sum(axis=2)\n# https://stackoverflow.com/a/57105712\npreds = np.c_[np.unravel_index(np.argpartition(band_08.ravel(),-n)[-n:],band_08.shape)]\nmask = np.zeros((256, 266))\nmask[preds[:, 0], preds[:, 1]] = 1\n\nplt.imshow(mask, cmap='Greys')\nplt.title(\"Obviously Not Contrails\", fontsize='16')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-06T11:43:00.909444Z","iopub.execute_input":"2023-05-06T11:43:00.909871Z","iopub.status.idle":"2023-05-06T11:43:01.204255Z","shell.execute_reply.started":"2023-05-06T11:43:00.909834Z","shell.execute_reply":"2023-05-06T11:43:01.203265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Convert to RLE","metadata":{}},{"cell_type":"code","source":"list_to_string(rle_encode(mask))","metadata":{"execution":{"iopub.status.busy":"2023-05-06T11:43:07.015849Z","iopub.execute_input":"2023-05-06T11:43:07.01631Z","iopub.status.idle":"2023-05-06T11:43:07.025396Z","shell.execute_reply.started":"2023-05-06T11:43:07.016272Z","shell.execute_reply":"2023-05-06T11:43:07.024113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Now let's automate a submission","metadata":{}},{"cell_type":"code","source":"submission = pd.read_csv(data_path / 'sample_submission.csv', index_col='record_id')\n\nfor rec in test_recs:\n    band_08 = np.load(data_path / 'test' / rec / 'band_08.npy').sum(axis=2)\n    preds = np.c_[np.unravel_index(np.argpartition(band_08.ravel(),-n)[-n:],band_08.shape)]\n    mask = np.zeros((256, 266))\n    mask[preds[:, 0], preds[:, 1]] = 1\n    # notice the we're converting rec to an `int` here:\n    submission.loc[int(rec), 'encoded_pixels'] = list_to_string(rle_encode(mask))\n\nsubmission.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-06T11:43:16.861866Z","iopub.execute_input":"2023-05-06T11:43:16.862256Z","iopub.status.idle":"2023-05-06T11:43:16.955922Z","shell.execute_reply.started":"2023-05-06T11:43:16.862224Z","shell.execute_reply":"2023-05-06T11:43:16.95506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv')","metadata":{"execution":{"iopub.status.busy":"2023-04-25T20:14:05.475792Z","iopub.execute_input":"2023-04-25T20:14:05.476624Z","iopub.status.idle":"2023-04-25T20:14:05.490396Z","shell.execute_reply.started":"2023-04-25T20:14:05.4765Z","shell.execute_reply":"2023-04-25T20:14:05.488648Z"},"trusted":true},"execution_count":null,"outputs":[]}]}