Skip to content

Instantly share code, notes, and snippets.

@dhermes
Last active January 3, 2020 19:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhermes/5c1f650690fd51c1746cc6c25c3c60ea to your computer and use it in GitHub Desktop.
Save dhermes/5c1f650690fd51c1746cc6c25c3c60ea to your computer and use it in GitHub Desktop.
Fitting a "hinged" piecewise linear function
.ipynb_checkpoints/
.venv/
__pycache__/

Fitting a "hinged" piecewise linear function

Run Notebook Server

python -m pip install --upgrade pip virtualenv
python -m virtualenv --python=python3.7 .venv
.venv/bin/python -m pip install --requirement requirements.txt
.venv/bin/jupyter notebook

Requirements

To update

python -m pip install --upgrade pip-tools  # For `pip-compile`
pip-compile \
  --generate-hashes \
  --upgrade \
  --output-file=requirements.txt \
  requirements.txt.in
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
import matplotlib.pyplot as plt
import numpy as np
import seaborn
def new_ax():
figure = plt.figure(figsize=(9, 6), dpi=80)
return figure.gca()
def plot_exact(h, a, b, c, x_start, x_end):
if not x_start < h < x_end:
raise ValueError("Invalid interval", x_start, h, x_end)
ax = new_ax()
x_vals = np.linspace(x_start, x_end, 1025)
delta_x = x_vals - h
y_vals = a + delta_x * np.where(delta_x <= 0.0, b, c)
ax.plot(x_vals, y_vals)
ax.plot([h], [a], marker="o", color="black")
def noisy_data(x_vals, h, a, b, c, seed):
delta_x = x_vals - h
y_vals_exact = a + delta_x * np.where(delta_x <= 0.0, b, c)
# Add some noise.
random_state = np.random.RandomState(seed=seed)
noise = random_state.randn(len(y_vals_exact))
y_vals = y_vals_exact * (1.0 + noise / 8.0)
return y_vals_exact, y_vals
def plot_noisy_data(h, a, x_vals, y_vals_exact, y_vals):
ax = new_ax()
ax.plot(
x_vals,
y_vals_exact,
marker="o",
alpha=0.5,
color="black",
linestyle="dashed",
)
ax.plot(x_vals, y_vals, marker="o")
ax.plot([h], [a], marker="o", color="black")
ax.set_xlabel("x", family="monospace")
ax.set_ylabel("y", rotation=0, family="monospace")
def plot_residuals(guesses, residuals_by_guess, annotated_x):
ax = new_ax()
ax.plot(guesses, residuals_by_guess)
annotated_y = []
for x_val in annotated_x:
nearest_guess = np.argmin(abs(guesses - x_val))
annotated_y.append(residuals_by_guess[nearest_guess])
ax.plot(
annotated_x, annotated_y, marker="o", linestyle="None", color="black"
)
ax.set_xlabel("guess(x_hinge)", family="monospace")
ax.set_ylabel("Residual")
def fit_coeffs(x_vals, y_vals, x_hinge):
num_vals = len(x_vals)
delta_x = x_vals - x_hinge
# y = A + B CHI(x <= x_hinge) (x - x_hinge) + C CHI(x > x_hinge) (x - x_hinge)
b_vals = np.where(delta_x <= 0.0, delta_x, 0.0)
c_vals = np.where(delta_x > 0.0, delta_x, 0.0)
a_vals = np.ones_like(b_vals)
lhs_mat = np.vstack([a_vals, b_vals, c_vals]).T
rhs_mat = y_vals[:, np.newaxis]
# coeffs, residuals, rank, singular_values
coeffs, residuals, _, _ = np.linalg.lstsq(lhs_mat, rhs_mat, rcond=None)
# Unpack the values
a, b, c = coeffs
residual, = residuals # Assumes y_vals is 1D
return a, b, c, residual
def find_hinge(x_vals, y_vals, num_guesses=65):
# NOTE: This assumes the hinge happens **within** the data.
min_residual = float("inf")
x_hinge_at_min = None
sorted_x = sorted(x_vals)
x_extrema = (sorted_x[0], sorted_x[-1])
for interval_start, interval_end in zip(sorted_x, sorted_x[1:]):
guesses = np.linspace(interval_start, interval_end, num_guesses)
for guess in guesses:
# NOTE: Since the hinge happens **within** the data, leave out
# the endpoints.
if guess in x_extrema:
continue
_, _, _, residual = fit_coeffs(x_vals, y_vals, guess)
if residual >= min_residual:
continue
min_residual = residual
x_hinge_at_min = guess
if x_hinge_at_min is None:
raise ValueError("No minimum was found")
a, b, c, _ = fit_coeffs(x_vals, y_vals, x_hinge_at_min)
return x_hinge_at_min, a, b, c
def describe_line(h, a, b, c):
# Cast from ``np.float64`` to ``float`` to avoid "shape" issues and other
# __str__ / __format__ differences.
h = float(h)
a = float(a)
b = float(b)
c = float(c)
if h <= 0 or a <= 0 or b <= 0 or c <= 0:
raise ValueError(
"describe_line only written for positive values", h, a, b, c
)
return "\n".join(
[
"y =",
r"\begin{cases}",
f"{a} + {b}(x - {h}), & \\text{{if }} x \leq {h} \\\\",
f"{a} + {c}(x - {h}), & \\text{{if }} x > {h}",
r"\end{cases}",
]
)
def plot_best_fit(h, a, b, c, x_vals, y_vals):
fit_x = np.sort(np.append(x_vals, h))
delta_x = fit_x - h
fit_y = a + delta_x * np.where(delta_x <= 0.0, b, c)
ax = new_ax()
ax.plot(fit_x, fit_y, alpha=0.5, color="black", linestyle="dashed")
ax.plot([h], [a], marker="o", color="black")
ax.plot(x_vals, y_vals, marker="o", linestyle="None")
ax.set_xlabel("x", family="monospace")
ax.set_ylabel("y", rotation=0, family="monospace")
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --generate-hashes --output-file=requirements.txt requirements.txt.in
#
appnope==0.1.0 \
--hash=sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0 \
--hash=sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71 \
# via ipykernel, ipython
attrs==19.3.0 \
--hash=sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c \
--hash=sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72 \
# via jsonschema
backcall==0.1.0 \
--hash=sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4 \
--hash=sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2 \
# via ipython
bleach==3.1.0 \
--hash=sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16 \
--hash=sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa \
# via nbconvert
cycler==0.10.0 \
--hash=sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d \
--hash=sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8 \
# via matplotlib
decorator==4.4.1 \
--hash=sha256:54c38050039232e1db4ad7375cfce6748d7b41c29e95a081c8a6d2c30364a2ce \
--hash=sha256:5d19b92a3c8f7f101c8dd86afd86b0f061a8ce4540ab8cd401fa2542756bce6d \
# via ipython, traitlets
defusedxml==0.6.0 \
--hash=sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93 \
--hash=sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5 \
# via nbconvert
entrypoints==0.3 \
--hash=sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19 \
--hash=sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451 \
# via nbconvert
importlib-metadata==1.3.0 \
--hash=sha256:073a852570f92da5f744a3472af1b61e28e9f78ccf0c9117658dc32b15de7b45 \
--hash=sha256:d95141fbfa7ef2ec65cfd945e2af7e5a6ddbd7c8d9a25e66ff3be8e3daf9f60f \
# via jsonschema
ipykernel==5.1.3 \
--hash=sha256:1a7def9c986f1ee018c1138d16951932d4c9d4da01dad45f9d34e9899565a22f \
--hash=sha256:b368ad13edb71fa2db367a01e755a925d7f75ed5e09fbd3f06c85e7a8ef108a8 \
# via ipywidgets, jupyter, jupyter-console, notebook, qtconsole
ipython-genutils==0.2.0 \
--hash=sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8 \
--hash=sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8 \
# via nbformat, notebook, qtconsole, traitlets
ipython==7.11.1 \
--hash=sha256:0f4bcf18293fb666df8511feec0403bdb7e061a5842ea6e88a3177b0ceb34ead \
--hash=sha256:387686dd7fc9caf29d2fddcf3116c4b07a11d9025701d220c589a430b0171d8a \
# via ipykernel, ipywidgets, jupyter-console
ipywidgets==7.5.1 \
--hash=sha256:13ffeca438e0c0f91ae583dc22f50379b9d6b28390ac7be8b757140e9a771516 \
--hash=sha256:e945f6e02854a74994c596d9db83444a1850c01648f1574adf144fbbabe05c97 \
# via jupyter
jedi==0.15.2 \
--hash=sha256:1349c1e8c107095a55386628bb3b2a79422f3a2cab8381e34ce19909e0cf5064 \
--hash=sha256:e909527104a903606dd63bea6e8e888833f0ef087057829b89a18364a856f807 \
# via ipython
jinja2==2.10.3 \
--hash=sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f \
--hash=sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de \
# via nbconvert, notebook
jsonschema==3.2.0 \
--hash=sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163 \
--hash=sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a \
# via nbformat
jupyter-client==5.3.4 \
--hash=sha256:60e6faec1031d63df57f1cc671ed673dced0ed420f4377ea33db37b1c188b910 \
--hash=sha256:d0c077c9aaa4432ad485e7733e4d91e48f87b4f4bab7d283d42bb24cbbba0a0f \
# via ipykernel, jupyter-console, notebook, qtconsole
jupyter-console==6.0.0 \
--hash=sha256:308ce876354924fb6c540b41d5d6d08acfc946984bf0c97777c1ddcb42e0b2f5 \
--hash=sha256:cc80a97a5c389cbd30252ffb5ce7cefd4b66bde98219edd16bf5cb6f84bb3568 \
# via jupyter
jupyter-core==4.6.1 \
--hash=sha256:464769f7387d7a62a2403d067f1ddc616655b7f77f5d810c0dd62cb54bfd0fb9 \
--hash=sha256:a183e0ec2e8f6adddf62b0a3fc6a2237e3e0056d381e536d3e7c7ecc3067e244 \
# via jupyter-client, nbconvert, nbformat, notebook, qtconsole
jupyter==1.0.0 \
--hash=sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7 \
--hash=sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78 \
--hash=sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f
kiwisolver==1.1.0 \
--hash=sha256:05b5b061e09f60f56244adc885c4a7867da25ca387376b02c1efc29cc16bcd0f \
--hash=sha256:210d8c39d01758d76c2b9a693567e1657ec661229bc32eac30761fa79b2474b0 \
--hash=sha256:26f4fbd6f5e1dabff70a9ba0d2c4bd30761086454aa30dddc5b52764ee4852b7 \
--hash=sha256:3b15d56a9cd40c52d7ab763ff0bc700edbb4e1a298dc43715ecccd605002cf11 \
--hash=sha256:3b2378ad387f49cbb328205bda569b9f87288d6bc1bf4cd683c34523a2341efe \
--hash=sha256:400599c0fe58d21522cae0e8b22318e09d9729451b17ee61ba8e1e7c0346565c \
--hash=sha256:47b8cb81a7d18dbaf4fed6a61c3cecdb5adec7b4ac292bddb0d016d57e8507d5 \
--hash=sha256:53eaed412477c836e1b9522c19858a8557d6e595077830146182225613b11a75 \
--hash=sha256:58e626e1f7dfbb620d08d457325a4cdac65d1809680009f46bf41eaf74ad0187 \
--hash=sha256:5a52e1b006bfa5be04fe4debbcdd2688432a9af4b207a3f429c74ad625022641 \
--hash=sha256:5c7ca4e449ac9f99b3b9d4693debb1d6d237d1542dd6a56b3305fe8a9620f883 \
--hash=sha256:682e54f0ce8f45981878756d7203fd01e188cc6c8b2c5e2cf03675390b4534d5 \
--hash=sha256:76275ee077772c8dde04fb6c5bc24b91af1bb3e7f4816fd1852f1495a64dad93 \
--hash=sha256:79bfb2f0bd7cbf9ea256612c9523367e5ec51d7cd616ae20ca2c90f575d839a2 \
--hash=sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3 \
--hash=sha256:8944a16020c07b682df861207b7e0efcd2f46c7488619cb55f65882279119389 \
--hash=sha256:8aa7009437640beb2768bfd06da049bad0df85f47ff18426261acecd1cf00897 \
--hash=sha256:9105ce82dcc32c73eb53a04c869b6a4bc756b43e4385f76ea7943e827f529e4d \
--hash=sha256:933df612c453928f1c6faa9236161a1d999a26cd40abf1dc5d7ebbc6dbfb8fca \
--hash=sha256:939f36f21a8c571686eb491acfffa9c7f1ac345087281b412d63ea39ca14ec4a \
--hash=sha256:9491578147849b93e70d7c1d23cb1229458f71fc79c51d52dce0809b2ca44eea \
--hash=sha256:9733b7f64bd9f807832d673355f79703f81f0b3e52bfce420fc00d8cb28c6a6c \
--hash=sha256:a02f6c3e229d0b7220bd74600e9351e18bc0c361b05f29adae0d10599ae0e326 \
--hash=sha256:a0c0a9f06872330d0dd31b45607197caab3c22777600e88031bfe66799e70bb0 \
--hash=sha256:aa716b9122307c50686356cfb47bfbc66541868078d0c801341df31dca1232a9 \
--hash=sha256:acc4df99308111585121db217681f1ce0eecb48d3a828a2f9bbf9773f4937e9e \
--hash=sha256:b64916959e4ae0ac78af7c3e8cef4becee0c0e9694ad477b4c6b3a536de6a544 \
--hash=sha256:d22702cadb86b6fcba0e6b907d9f84a312db9cd6934ee728144ce3018e715ee1 \
--hash=sha256:d3fcf0819dc3fea58be1fd1ca390851bdb719a549850e708ed858503ff25d995 \
--hash=sha256:d52e3b1868a4e8fd18b5cb15055c76820df514e26aa84cc02f593d99fef6707f \
--hash=sha256:db1a5d3cc4ae943d674718d6c47d2d82488ddd94b93b9e12d24aabdbfe48caee \
--hash=sha256:e3a21a720791712ed721c7b95d433e036134de6f18c77dbe96119eaf7aa08004 \
--hash=sha256:e8bf074363ce2babeb4764d94f8e65efd22e6a7c74860a4f05a6947afc020ff2 \
--hash=sha256:f16814a4a96dc04bf1da7d53ee8d5b1d6decfc1a92a63349bb15d37b6a263dd9 \
--hash=sha256:f2b22153870ca5cf2ab9c940d7bc38e8e9089fa0f7e5856ea195e1cf4ff43d5a \
--hash=sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f \
--hash=sha256:fe51b79da0062f8e9d49ed0182a626a7dc7a0cbca0328f612c6ee5e4711c81e4 \
# via matplotlib
markupsafe==1.1.1 \
--hash=sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473 \
--hash=sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161 \
--hash=sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235 \
--hash=sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5 \
--hash=sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff \
--hash=sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b \
--hash=sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1 \
--hash=sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e \
--hash=sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183 \
--hash=sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66 \
--hash=sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1 \
--hash=sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1 \
--hash=sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e \
--hash=sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b \
--hash=sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905 \
--hash=sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735 \
--hash=sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d \
--hash=sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e \
--hash=sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d \
--hash=sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c \
--hash=sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21 \
--hash=sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2 \
--hash=sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5 \
--hash=sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b \
--hash=sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6 \
--hash=sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f \
--hash=sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f \
--hash=sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7 \
# via jinja2
matplotlib==3.1.2 \
--hash=sha256:08ccc8922eb4792b91c652d3e6d46b1c99073f1284d1b6705155643e8046463a \
--hash=sha256:161dcd807c0c3232f4dcd4a12a382d52004a498174cbfafd40646106c5bcdcc8 \
--hash=sha256:1f9e885bfa1b148d16f82a6672d043ecf11197f6c71ae222d0546db706e52eb2 \
--hash=sha256:2d6ab54015a7c0d727c33e36f85f5c5e4172059efdd067f7527f6e5d16ad01aa \
--hash=sha256:5d2e408a2813abf664bd79431107543ecb449136912eb55bb312317edecf597e \
--hash=sha256:61c8b740a008218eb604de518eb411c4953db0cb725dd0b32adf8a81771cab9e \
--hash=sha256:80f10af8378fccc136da40ea6aa4a920767476cdfb3241acb93ef4f0465dbf57 \
--hash=sha256:819d4860315468b482f38f1afe45a5437f60f03eaede495d5ff89f2eeac89500 \
--hash=sha256:8cc0e44905c2c8fda5637cad6f311eb9517017515a034247ab93d0cf99f8bb7a \
--hash=sha256:8e8e2c2fe3d873108735c6ee9884e6f36f467df4a143136209cff303b183bada \
--hash=sha256:98c2ffeab8b79a4e3a0af5dd9939f92980eb6e3fec10f7f313df5f35a84dacab \
--hash=sha256:d59bb0e82002ac49f4152963f8a1079e66794a4f454457fd2f0dcc7bf0797d30 \
--hash=sha256:ee59b7bb9eb75932fe3787e54e61c99b628155b0cedc907864f24723ba55b309
mistune==0.8.4 \
--hash=sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e \
--hash=sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4 \
# via nbconvert
more-itertools==8.0.2 \
--hash=sha256:b84b238cce0d9adad5ed87e745778d20a3f8487d0f0cb8b8a586816c7496458d \
--hash=sha256:c833ef592a0324bcc6a60e48440da07645063c453880c9477ceb22490aec1564 \
# via zipp
nbconvert==5.6.1 \
--hash=sha256:21fb48e700b43e82ba0e3142421a659d7739b65568cc832a13976a77be16b523 \
--hash=sha256:f0d6ec03875f96df45aa13e21fd9b8450c42d7e1830418cccc008c0df725fcee \
# via jupyter, notebook
nbformat==4.4.0 \
--hash=sha256:b9a0dbdbd45bb034f4f8893cafd6f652ea08c8c1674ba83f2dc55d3955743b0b \
--hash=sha256:f7494ef0df60766b7cabe0a3651556345a963b74dbc16bc7c18479041170d402 \
# via ipywidgets, nbconvert, notebook
notebook==6.0.2 \
--hash=sha256:399a4411e171170173344761e7fd4491a3625659881f76ce47c50231ed714d9b \
--hash=sha256:f67d76a68b1074a91693e95dea903ea01fd02be7c9fac5a4b870b8475caed805 \
# via jupyter, widgetsnbextension
numpy==1.18.0 \
--hash=sha256:03bbde29ac8fba860bb2c53a1525b3604a9b60417855ac3119d89868ec6041c3 \
--hash=sha256:1baefd1fb4695e7f2e305467dbd876d765e6edd30c522894df76f8301efaee36 \
--hash=sha256:1c35fb1131362e6090d30286cfda52ddd42e69d3e2bf1fea190a0fad83ea3a18 \
--hash=sha256:3c68c827689ca0ca713dba598335073ce0966850ec0b30715527dce4ecd84055 \
--hash=sha256:443ab93fc35b31f01db8704681eb2fd82f3a1b2fa08eed2dd0e71f1f57423d4a \
--hash=sha256:56710a756c5009af9f35b91a22790701420406d9ac24cf6b652b0e22cfbbb7ff \
--hash=sha256:62506e9e4d2a39c87984f081a2651d4282a1d706b1a82fe9d50a559bb58e705a \
--hash=sha256:6f8113c8dbfc192b58996ee77333696469ea121d1c44ea429d8fd266e4c6be51 \
--hash=sha256:712f0c32555132f4b641b918bdb1fd3c692909ae916a233ce7f50eac2de87e37 \
--hash=sha256:854f6ed4fa91fa6da5d764558804ba5b0f43a51e5fe9fc4fdc93270b052f188a \
--hash=sha256:88c5ccbc4cadf39f32193a5ef22e3f84674418a9fd877c63322917ae8f295a56 \
--hash=sha256:905cd6fa6ac14654a6a32b21fad34670e97881d832e24a3ca32e19b455edb4a8 \
--hash=sha256:9d6de2ad782aae68f7ed0e0e616477fbf693d6d7cc5f0f1505833ff12f84a673 \
--hash=sha256:a30f5c3e1b1b5d16ec1f03f4df28e08b8a7529d8c920bbed657f4fde61f1fbcd \
--hash=sha256:a9d72d9abaf65628f0f31bbb573b7d9304e43b1e6bbae43149c17737a42764c4 \
--hash=sha256:ac3cf835c334fcc6b74dc4e630f9b5ff7b4c43f7fb2a7813208d95d4e10b5623 \
--hash=sha256:b091e5d4cbbe79f0e8b6b6b522346e54a282eadb06e3fd761e9b6fafc2ca91ad \
--hash=sha256:cc070fc43a494e42732d6ae2f6621db040611c1dde64762a40c8418023af56d7 \
--hash=sha256:e1080e37c090534adb2dd7ae1c59ee883e5d8c3e63d2a4d43c20ee348d0459c5 \
--hash=sha256:f084d513de729ff10cd72a1f80db468cff464fedb1ef2fea030221a0f62d7ff4 \
--hash=sha256:f6a7421da632fc01e8a3ecd19c3f7350258d82501a646747664bae9c6a87c731
pandas==0.25.3 \
--hash=sha256:00dff3a8e337f5ed7ad295d98a31821d3d0fe7792da82d78d7fd79b89c03ea9d \
--hash=sha256:22361b1597c8c2ffd697aa9bf85423afa9e1fcfa6b1ea821054a244d5f24d75e \
--hash=sha256:255920e63850dc512ce356233081098554d641ba99c3767dde9e9f35630f994b \
--hash=sha256:26382aab9c119735908d94d2c5c08020a4a0a82969b7e5eefb92f902b3b30ad7 \
--hash=sha256:33970f4cacdd9a0ddb8f21e151bfb9f178afb7c36eb7c25b9094c02876f385c2 \
--hash=sha256:4545467a637e0e1393f7d05d61dace89689ad6d6f66f267f86fff737b702cce9 \
--hash=sha256:52da74df8a9c9a103af0a72c9d5fdc8e0183a90884278db7f386b5692a2220a4 \
--hash=sha256:61741f5aeb252f39c3031d11405305b6d10ce663c53bc3112705d7ad66c013d0 \
--hash=sha256:6a3ac2c87e4e32a969921d1428525f09462770c349147aa8e9ab95f88c71ec71 \
--hash=sha256:7458c48e3d15b8aaa7d575be60e1e4dd70348efcd9376656b72fecd55c59a4c3 \
--hash=sha256:78bf638993219311377ce9836b3dc05f627a666d0dbc8cec37c0ff3c9ada673b \
--hash=sha256:8153705d6545fd9eb6dd2bc79301bff08825d2e2f716d5dced48daafc2d0b81f \
--hash=sha256:975c461accd14e89d71772e89108a050fa824c0b87a67d34cedf245f6681fc17 \
--hash=sha256:9962957a27bfb70ab64103d0a7b42fa59c642fb4ed4cb75d0227b7bb9228535d \
--hash=sha256:adc3d3a3f9e59a38d923e90e20c4922fc62d1e5a03d083440468c6d8f3f1ae0a \
--hash=sha256:bbe3eb765a0b1e578833d243e2814b60c825b7fdbf4cdfe8e8aae8a08ed56ecf \
--hash=sha256:df8864824b1fe488cf778c3650ee59c3a0d8f42e53707de167ba6b4f7d35f133 \
--hash=sha256:e45055c30a608076e31a9fcd780a956ed3b1fa20db61561b8d88b79259f526f7 \
--hash=sha256:ee50c2142cdcf41995655d499a157d0a812fce55c97d9aad13bc1eef837ed36c \
# via seaborn
pandocfilters==1.4.2 \
--hash=sha256:b3dd70e169bb5449e6bc6ff96aea89c5eea8c5f6ab5e207fc2f521a2cf4a0da9 \
# via nbconvert
parso==0.5.2 \
--hash=sha256:55cf25df1a35fd88b878715874d2c4dc1ad3f0eebd1e0266a67e1f55efccfbe1 \
--hash=sha256:5c1f7791de6bd5dbbeac8db0ef5594b36799de198b3f7f7014643b0c5536b9d3 \
# via jedi
pexpect==4.7.0 \
--hash=sha256:2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1 \
--hash=sha256:9e2c1fd0e6ee3a49b28f95d4b33bc389c89b20af6a1255906e90ff1262ce62eb \
# via ipython
pickleshare==0.7.5 \
--hash=sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca \
--hash=sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56 \
# via ipython
prometheus-client==0.7.1 \
--hash=sha256:71cd24a2b3eb335cb800c7159f423df1bd4dcd5171b234be15e3f31ec9f622da \
# via notebook
prompt-toolkit==2.0.10 \
--hash=sha256:46642344ce457641f28fc9d1c9ca939b63dadf8df128b86f1b9860e59c73a5e4 \
--hash=sha256:e7f8af9e3d70f514373bf41aa51bc33af12a6db3f71461ea47fea985defb2c31 \
--hash=sha256:f15af68f66e664eaa559d4ac8a928111eebd5feda0c11738b5998045224829db \
# via ipython, jupyter-console
ptyprocess==0.6.0 \
--hash=sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0 \
--hash=sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f \
# via pexpect, terminado
pygments==2.5.2 \
--hash=sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b \
--hash=sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe \
# via ipython, jupyter-console, nbconvert, qtconsole
pyparsing==2.4.6 \
--hash=sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f \
--hash=sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec \
# via matplotlib
pyrsistent==0.15.6 \
--hash=sha256:f3b280d030afb652f79d67c5586157c5c1355c9a58dfc7940566e28d28f3df1b \
# via jsonschema
python-dateutil==2.8.1 \
--hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \
--hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a \
# via jupyter-client, matplotlib, pandas
pytz==2019.3 \
--hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \
--hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be \
# via pandas
pyzmq==18.1.1 \
--hash=sha256:01b588911714a6696283de3904f564c550c9e12e8b4995e173f1011755e01086 \
--hash=sha256:0573b9790aa26faff33fba40f25763657271d26f64bffb55a957a3d4165d6098 \
--hash=sha256:0fa82b9fc3334478be95a5566f35f23109f763d1669bb762e3871a8fa2a4a037 \
--hash=sha256:1e59b7b19396f26e360f41411a5d4603356d18871049cd7790f1a7d18f65fb2c \
--hash=sha256:2a294b4f44201bb21acc2c1a17ff87fbe57b82060b10ddb00ac03e57f3d7fcfa \
--hash=sha256:355b38d7dd6f884b8ee9771f59036bcd178d98539680c4f87e7ceb2c6fd057b6 \
--hash=sha256:4b73d20aec63933bbda7957e30add233289d86d92a0bb9feb3f4746376f33527 \
--hash=sha256:4ec47f2b50bdb97df58f1697470e5c58c3c5109289a623e30baf293481ff0166 \
--hash=sha256:5541dc8cad3a8486d58bbed076cb113b65b5dd6b91eb94fb3e38a3d1d3022f20 \
--hash=sha256:6fca7d11310430e751f9832257866a122edf9d7b635305c5d8c51f74a5174d3d \
--hash=sha256:7369656f89878455a5bcd5d56ca961884f5d096268f71c0750fc33d6732a25e5 \
--hash=sha256:75d73ee7ca4b289a2a2dfe0e6bd8f854979fc13b3fe4ebc19381be3b04e37a4a \
--hash=sha256:80c928d5adcfa12346b08d31360988d843b54b94154575cccd628f1fe91446bc \
--hash=sha256:83ce18b133dc7e6789f64cb994e7376c5aa6b4aeced993048bf1d7f9a0fe6d3a \
--hash=sha256:8b8498ceee33a7023deb2f3db907ca41d6940321e282297327a9be41e3983792 \
--hash=sha256:8c69a6cbfa94da29a34f6b16193e7c15f5d3220cb772d6d17425ff3faa063a6d \
--hash=sha256:8ff946b20d13a99dc5c21cb76f4b8b253eeddf3eceab4218df8825b0c65ab23d \
--hash=sha256:972d723a36ab6a60b7806faa5c18aa3c080b7d046c407e816a1d8673989e2485 \
--hash=sha256:a6c9c42bbdba3f9c73aedbb7671815af1943ae8073e532c2b66efb72f39f4165 \
--hash=sha256:aa3872f2ebfc5f9692ef8957fe69abe92d905a029c0608e45ebfcd451ad30ab5 \
--hash=sha256:cf08435b14684f7f2ca2df32c9df38a79cdc17c20dc461927789216cb43d8363 \
--hash=sha256:d30db4566177a6205ed1badb8dbbac3c043e91b12a2db5ef9171b318c5641b75 \
--hash=sha256:d5ac84f38575a601ab20c1878818ffe0d09eb51d6cb8511b636da46d0fd8949a \
--hash=sha256:e37f22eb4bfbf69cd462c7000616e03b0cdc1b65f2d99334acad36ea0e4ddf6b \
--hash=sha256:e6549dd80de7b23b637f586217a4280facd14ac01e9410a037a13854a6977299 \
--hash=sha256:ed6205ca0de035f252baa0fd26fdd2bc8a8f633f92f89ca866fd423ff26c6f25 \
--hash=sha256:efdde21febb9b5d7a8e0b87ea2549d7e00fda1936459cfb27fb6fca0c36af6c1 \
--hash=sha256:f4e72646bfe79ff3adbf1314906bbd2d67ef9ccc71a3a98b8b2ccbcca0ab7bec \
# via jupyter-client, notebook
qtconsole==4.6.0 \
--hash=sha256:4de25b8895957d23ceacf2526b6f0a76da4e60e60115611930d387c853f3cb08 \
--hash=sha256:654f423662e7dfe6a9b26fac8ec76aedcf742c339909ac49f1f0c1a1b744bcd1 \
# via jupyter
scipy==1.4.1 \
--hash=sha256:00af72998a46c25bdb5824d2b729e7dabec0c765f9deb0b504f928591f5ff9d4 \
--hash=sha256:0902a620a381f101e184a958459b36d3ee50f5effd186db76e131cbefcbb96f7 \
--hash=sha256:1e3190466d669d658233e8a583b854f6386dd62d655539b77b3fa25bfb2abb70 \
--hash=sha256:2cce3f9847a1a51019e8c5b47620da93950e58ebc611f13e0d11f4980ca5fecb \
--hash=sha256:3092857f36b690a321a662fe5496cb816a7f4eecd875e1d36793d92d3f884073 \
--hash=sha256:386086e2972ed2db17cebf88610aab7d7f6e2c0ca30042dc9a89cf18dcc363fa \
--hash=sha256:71eb180f22c49066f25d6df16f8709f215723317cc951d99e54dc88020ea57be \
--hash=sha256:770254a280d741dd3436919d47e35712fb081a6ff8bafc0f319382b954b77802 \
--hash=sha256:787cc50cab3020a865640aba3485e9fbd161d4d3b0d03a967df1a2881320512d \
--hash=sha256:8a07760d5c7f3a92e440ad3aedcc98891e915ce857664282ae3c0220f3301eb6 \
--hash=sha256:8d3bc3993b8e4be7eade6dcc6fd59a412d96d3a33fa42b0fa45dc9e24495ede9 \
--hash=sha256:9508a7c628a165c2c835f2497837bf6ac80eb25291055f56c129df3c943cbaf8 \
--hash=sha256:a144811318853a23d32a07bc7fd5561ff0cac5da643d96ed94a4ffe967d89672 \
--hash=sha256:a1aae70d52d0b074d8121333bc807a485f9f1e6a69742010b33780df2e60cfe0 \
--hash=sha256:a2d6df9eb074af7f08866598e4ef068a2b310d98f87dc23bd1b90ec7bdcec802 \
--hash=sha256:bb517872058a1f087c4528e7429b4a44533a902644987e7b2fe35ecc223bc408 \
--hash=sha256:c5cac0c0387272ee0e789e94a570ac51deb01c796b37fb2aad1fb13f85e2f97d \
--hash=sha256:cc971a82ea1170e677443108703a2ec9ff0f70752258d0e9f5433d00dda01f59 \
--hash=sha256:dba8306f6da99e37ea08c08fef6e274b5bf8567bb094d1dbe86a20e532aca088 \
--hash=sha256:dc60bb302f48acf6da8ca4444cfa17d52c63c5415302a9ee77b3b21618090521 \
--hash=sha256:dee1bbf3a6c8f73b6b218cb28eed8dd13347ea2f87d572ce19b289d6fd3fbc59 \
# via seaborn
seaborn==0.9.0 \
--hash=sha256:42e627b24e849c2d3bbfd059e00005f6afbc4a76e4895baf44ae23fe8a4b09a5 \
--hash=sha256:76c83f794ca320fb6b23a7c6192d5e185a5fcf4758966a0c0a54baee46d41e2f
send2trash==1.5.0 \
--hash=sha256:60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2 \
--hash=sha256:f1691922577b6fa12821234aeb57599d887c4900b9ca537948d2dac34aea888b \
# via notebook
six==1.13.0 \
--hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \
--hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66 \
# via bleach, cycler, jsonschema, prompt-toolkit, pyrsistent, python-dateutil, traitlets
terminado==0.8.3 \
--hash=sha256:4804a774f802306a7d9af7322193c5390f1da0abb429e082a10ef1d46e6fb2c2 \
--hash=sha256:a43dcb3e353bc680dd0783b1d9c3fc28d529f190bc54ba9a229f72fe6e7a54d7 \
# via notebook
testpath==0.4.4 \
--hash=sha256:60e0a3261c149755f4399a1fff7d37523179a70fdc3abdf78de9fc2604aeec7e \
--hash=sha256:bfcf9411ef4bf3db7579063e0546938b1edda3d69f4e1fb8756991f5951f85d4 \
# via nbconvert
tornado==6.0.3 \
--hash=sha256:349884248c36801afa19e342a77cc4458caca694b0eda633f5878e458a44cb2c \
--hash=sha256:398e0d35e086ba38a0427c3b37f4337327231942e731edaa6e9fd1865bbd6f60 \
--hash=sha256:4e73ef678b1a859f0cb29e1d895526a20ea64b5ffd510a2307b5998c7df24281 \
--hash=sha256:559bce3d31484b665259f50cd94c5c28b961b09315ccd838f284687245f416e5 \
--hash=sha256:abbe53a39734ef4aba061fca54e30c6b4639d3e1f59653f0da37a0003de148c7 \
--hash=sha256:c845db36ba616912074c5b1ee897f8e0124df269468f25e4fe21fe72f6edd7a9 \
--hash=sha256:c9399267c926a4e7c418baa5cbe91c7d1cf362d505a1ef898fde44a07c9dd8a5 \
# via ipykernel, jupyter-client, notebook, terminado
traitlets==4.3.3 \
--hash=sha256:70b4c6a1d9019d7b4f6846832288f86998aa3b9207c6821f3578a6a6a467fe44 \
--hash=sha256:d023ee369ddd2763310e4c3eae1ff649689440d4ae59d7485eb4cfbbe3e359f7 \
# via ipykernel, ipython, ipywidgets, jupyter-client, jupyter-core, nbconvert, nbformat, notebook, qtconsole
wcwidth==0.1.8 \
--hash=sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603 \
# via prompt-toolkit
webencodings==0.5.1 \
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
--hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 \
# via bleach
widgetsnbextension==3.5.1 \
--hash=sha256:079f87d87270bce047512400efd70238820751a11d2d8cb137a5a5bdbaf255c7 \
--hash=sha256:bd314f8ceb488571a5ffea6cc5b9fc6cba0adaf88a9d2386b93a489751938bcd \
# via ipywidgets
zipp==0.6.0 \
--hash=sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e \
--hash=sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335 \
# via importlib-metadata
# WARNING: The following packages were not pinned, but pip requires them to be
# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag.
# setuptools
matplotlib
numpy
jupyter
seaborn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment