Skip to content

Instantly share code, notes, and snippets.

@petigura
Last active December 19, 2024 19:10
Show Gist options
  • Select an option

  • Save petigura/b0c539295689a4b4aacc5d3bb0ce9a5c to your computer and use it in GitHub Desktop.

Select an option

Save petigura/b0c539295689a4b4aacc5d3bb0ce9a5c to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"id": "b1187aa0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using matplotlib backend: MacOSX\n",
"%pylab is deprecated, use %matplotlib inline and import the required libraries.\n",
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"%pylab\n",
"import pandas as pd"
]
},
{
"cell_type": "markdown",
"id": "b6f19810",
"metadata": {},
"source": [
"# Create a simulated schedule"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "9e5122e3",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th>r</th>\n",
" <th>d</th>\n",
" <th>s</th>\n",
" <th>D_intra</th>\n",
" <th>D_inter</th>\n",
" <th>ns</th>\n",
" </tr>\n",
" <tr>\n",
" <th>r_id</th>\n",
" <th>d_id</th>\n",
" <th>s_id</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th rowspan=\"5\" valign=\"top\">0</th>\n",
" <th rowspan=\"5\" valign=\"top\">0</th>\n",
" <th>1</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>26</td>\n",
" <td>9</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>4</td>\n",
" <td>26</td>\n",
" <td>9</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>5</td>\n",
" <td>26</td>\n",
" <td>9</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>6</td>\n",
" <td>26</td>\n",
" <td>9</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>9</td>\n",
" <td>26</td>\n",
" <td>9</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <th>...</th>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th rowspan=\"5\" valign=\"top\">99</th>\n",
" <th rowspan=\"5\" valign=\"top\">184</th>\n",
" <th>88</th>\n",
" <td>99</td>\n",
" <td>184</td>\n",
" <td>88</td>\n",
" <td>33</td>\n",
" <td>9</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>89</th>\n",
" <td>99</td>\n",
" <td>184</td>\n",
" <td>89</td>\n",
" <td>33</td>\n",
" <td>9</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>91</th>\n",
" <td>99</td>\n",
" <td>184</td>\n",
" <td>91</td>\n",
" <td>33</td>\n",
" <td>9</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>93</th>\n",
" <td>99</td>\n",
" <td>184</td>\n",
" <td>93</td>\n",
" <td>33</td>\n",
" <td>9</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>96</th>\n",
" <td>99</td>\n",
" <td>184</td>\n",
" <td>96</td>\n",
" <td>33</td>\n",
" <td>9</td>\n",
" <td>4</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>500000 rows × 6 columns</p>\n",
"</div>"
],
"text/plain": [
" r d s D_intra D_inter ns\n",
"r_id d_id s_id \n",
"0 0 1 0 0 1 26 9 1\n",
" 4 0 0 4 26 9 1\n",
" 5 0 0 5 26 9 1\n",
" 6 0 0 6 26 9 1\n",
" 9 0 0 9 26 9 1\n",
"... .. ... .. ... ... ..\n",
"99 184 88 99 184 88 33 9 4\n",
" 89 99 184 89 33 9 4\n",
" 91 99 184 91 33 9 4\n",
" 93 99 184 93 33 9 4\n",
" 96 99 184 96 33 9 4\n",
"\n",
"[500000 rows x 6 columns]"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.seed(0)\n",
"n_large_rows = 1_000_000\n",
"df = pd.DataFrame({\n",
" 'r': np.random.randint(0, 100, size=n_large_rows),\n",
" 'd': np.random.randint(0, 185, size=n_large_rows),\n",
" 's': np.random.randint(0, 100, size=n_large_rows)\n",
"})\n",
"\n",
"temp = df[['r']].drop_duplicates()\n",
"temp['D_intra'] = np.random.randint(10,50,len(temp))\n",
"temp['D_inter'] = np.random.randint(0,10,len(temp))\n",
"temp['ns'] = np.random.randint(0,10,len(temp)) \n",
"df = pd.merge(df,temp,on='r')\n",
"df = df.drop_duplicates().head(int(n_large_rows / 2)) # remove duplicate tuples\n",
"\n",
"df2 = df.set_index(['r','d','s'])\n",
"df2 = df2.rename_axis(index={'r': 'r_id', 'd': 'd_id','s':'s_id'})\n",
"\n",
"df = pd.DataFrame(df.values, columns=df.columns, index=df2.index)\n",
"df = df.sort_values(by=['r','d','s'])\n",
"df"
]
},
{
"cell_type": "markdown",
"id": "2d7d6322",
"metadata": {},
"source": [
"# tuples for intra-night cadence constraint"
]
},
{
"cell_type": "code",
"execution_count": 90,
"id": "b6e91763",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"r d s \n",
"20 0 1 [4, 8, 9, 10, 12]\n",
" 4 [8, 9, 10, 12, 14]\n",
" 8 [10, 12, 14, 16, 17]\n",
" 9 [12, 14, 16, 17, 20]\n",
" 10 [12, 14, 16, 17, 20]\n",
" ... \n",
" 184 83 [86, 90, 93, 94]\n",
" 86 [90, 93, 94]\n",
" 90 [93, 94, 99]\n",
" 93 [99]\n",
" 94 [99]\n",
"Name: s2, Length: 7477, dtype: object"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Let's suppose requests 20 and 30 is the only target with an intra-night cadence request\n",
"# we'll need to loop over these requests, days, and slots For each (r,d,s) we'll need to query the \n",
"# set of (r,d,s) slots that are within s + delta, delta = {1,...,Delta_intra}\n",
"\n",
"r_intra = [20,30,45,50] # subset of requests with intra-night constraints\n",
"df2 = df[df.r.isin(r_intra)] # create subset of requests\n",
"# compute the cartestian product of all r,d,s,s2, but only return the ones within where s2 is within D_intra of s\n",
"df2 = pd.merge(df2,df2[['r','d','s']],on=['r','d'],suffixes=['','2']).query('s + 1 < s2 < s + D_intra')\n",
"df2.groupby(['r','d','s'])['s2'].agg(list)"
]
},
{
"cell_type": "markdown",
"id": "d5fac65c",
"metadata": {},
"source": [
"# all unique (r,d)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "09c13441",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th>r</th>\n",
" <th>d</th>\n",
" </tr>\n",
" <tr>\n",
" <th>r_id</th>\n",
" <th>d_id</th>\n",
" <th>s_id</th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th rowspan=\"5\" valign=\"top\">0</th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <th>0</th>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <th>1</th>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <th>3</th>\n",
" <td>0</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <th>2</th>\n",
" <td>0</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <th>...</th>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th rowspan=\"5\" valign=\"top\">99</th>\n",
" <th>180</th>\n",
" <th>1</th>\n",
" <td>99</td>\n",
" <td>180</td>\n",
" </tr>\n",
" <tr>\n",
" <th>181</th>\n",
" <th>2</th>\n",
" <td>99</td>\n",
" <td>181</td>\n",
" </tr>\n",
" <tr>\n",
" <th>182</th>\n",
" <th>0</th>\n",
" <td>99</td>\n",
" <td>182</td>\n",
" </tr>\n",
" <tr>\n",
" <th>183</th>\n",
" <th>0</th>\n",
" <td>99</td>\n",
" <td>183</td>\n",
" </tr>\n",
" <tr>\n",
" <th>184</th>\n",
" <th>0</th>\n",
" <td>99</td>\n",
" <td>184</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>12025 rows × 2 columns</p>\n",
"</div>"
],
"text/plain": [
" r d\n",
"r_id d_id s_id \n",
"0 0 1 0 0\n",
" 1 0 0 1\n",
" 2 1 0 2\n",
" 3 3 0 3\n",
" 4 2 0 4\n",
"... .. ...\n",
"99 180 1 99 180\n",
" 181 2 99 181\n",
" 182 0 99 182\n",
" 183 0 99 183\n",
" 184 0 99 184\n",
"\n",
"[12025 rows x 2 columns]"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df2 = df[['r','d']].drop_duplicates()\n",
"df2"
]
},
{
"cell_type": "markdown",
"id": "23adaadf",
"metadata": {},
"source": [
"# tuples for inter-night cadence constraint"
]
},
{
"cell_type": "code",
"execution_count": 91,
"id": "ee40e15e",
"metadata": {},
"outputs": [],
"source": [
"# compute the cartestian product of all r,d,d2,s but only return the ones within where d2 is within D_inter of d\n",
"df2 = pd.merge(\n",
" df.drop_duplicates(['r','d']), # only need one row per (r,d) pair\n",
" df[['r','d','s']], #\n",
" suffixes=['','2'],on=['r'] \n",
").query('d + 1 < d2 < d + D_inter')"
]
},
{
"cell_type": "code",
"execution_count": 89,
"id": "8ca14015",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th></th>\n",
" <th>d2</th>\n",
" <th>s2</th>\n",
" </tr>\n",
" <tr>\n",
" <th>r</th>\n",
" <th>d</th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th rowspan=\"5\" valign=\"top\">0</th>\n",
" <th>0</th>\n",
" <td>[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...</td>\n",
" <td>[1, 2, 5, 9, 14, 15, 18, 21, 23, 24, 31, 32, 3...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ...</td>\n",
" <td>[3, 5, 7, 8, 10, 12, 16, 20, 21, 23, 24, 25, 2...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>[4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, ...</td>\n",
" <td>[2, 4, 7, 8, 10, 11, 14, 16, 17, 18, 22, 24, 2...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>[5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ...</td>\n",
" <td>[1, 2, 3, 5, 14, 15, 20, 25, 26, 30, 31, 32, 3...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, ...</td>\n",
" <td>[5, 8, 10, 12, 15, 20, 21, 22, 27, 29, 36, 38,...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th rowspan=\"5\" valign=\"top\">99</th>\n",
" <th>178</th>\n",
" <td>[180, 180, 180, 180, 180, 180, 180, 180, 180, ...</td>\n",
" <td>[1, 2, 4, 6, 8, 9, 11, 15, 17, 19, 24, 27, 28,...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>179</th>\n",
" <td>[181, 181, 181, 181, 181, 181, 181, 181, 181, ...</td>\n",
" <td>[2, 3, 6, 9, 10, 13, 15, 16, 17, 18, 19, 20, 2...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>180</th>\n",
" <td>[182, 182, 182, 182, 182, 182, 182, 182, 182, ...</td>\n",
" <td>[0, 2, 3, 4, 11, 12, 15, 16, 20, 24, 29, 32, 3...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>181</th>\n",
" <td>[183, 183, 183, 183, 183, 183, 183, 183, 183, ...</td>\n",
" <td>[0, 3, 5, 7, 11, 15, 16, 17, 18, 21, 23, 24, 2...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>182</th>\n",
" <td>[184, 184, 184, 184, 184, 184, 184, 184, 184, ...</td>\n",
" <td>[0, 1, 3, 4, 8, 10, 12, 16, 18, 20, 23, 26, 27...</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>8418 rows × 2 columns</p>\n",
"</div>"
],
"text/plain": [
" d2 \\\n",
"r d \n",
"0 0 [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ... \n",
" 1 [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ... \n",
" 2 [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, ... \n",
" 3 [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ... \n",
" 4 [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, ... \n",
"... ... \n",
"99 178 [180, 180, 180, 180, 180, 180, 180, 180, 180, ... \n",
" 179 [181, 181, 181, 181, 181, 181, 181, 181, 181, ... \n",
" 180 [182, 182, 182, 182, 182, 182, 182, 182, 182, ... \n",
" 181 [183, 183, 183, 183, 183, 183, 183, 183, 183, ... \n",
" 182 [184, 184, 184, 184, 184, 184, 184, 184, 184, ... \n",
"\n",
" s2 \n",
"r d \n",
"0 0 [1, 2, 5, 9, 14, 15, 18, 21, 23, 24, 31, 32, 3... \n",
" 1 [3, 5, 7, 8, 10, 12, 16, 20, 21, 23, 24, 25, 2... \n",
" 2 [2, 4, 7, 8, 10, 11, 14, 16, 17, 18, 22, 24, 2... \n",
" 3 [1, 2, 3, 5, 14, 15, 20, 25, 26, 30, 31, 32, 3... \n",
" 4 [5, 8, 10, 12, 15, 20, 21, 22, 27, 29, 36, 38,... \n",
"... ... \n",
"99 178 [1, 2, 4, 6, 8, 9, 11, 15, 17, 19, 24, 27, 28,... \n",
" 179 [2, 3, 6, 9, 10, 13, 15, 16, 17, 18, 19, 20, 2... \n",
" 180 [0, 2, 3, 4, 11, 12, 15, 16, 20, 24, 29, 32, 3... \n",
" 181 [0, 3, 5, 7, 11, 15, 16, 17, 18, 21, 23, 24, 2... \n",
" 182 [0, 1, 3, 4, 8, 10, 12, 16, 18, 20, 23, 26, 27... \n",
"\n",
"[8418 rows x 2 columns]"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df2.groupby(['r','d'])[['d2','s2']].agg(list)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.19"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment