Skip to content

Instantly share code, notes, and snippets.

@gakonst
Last active March 12, 2020 21:33
Show Gist options
  • Select an option

  • Save gakonst/d00af7085a47ad6235fb7489a2c5b600 to your computer and use it in GitHub Desktop.

Select an option

Save gakonst/d00af7085a47ad6235fb7489a2c5b600 to your computer and use it in GitHub Desktop.

Revisions

  1. gakonst revised this gist Mar 12, 2020. 2 changed files with 27 additions and 23 deletions.
    48 changes: 26 additions & 22 deletions covid19.py
    Original file line number Diff line number Diff line change
    @@ -37,10 +37,6 @@
    growth = diff / infections_per_day[i-1]
    growth_rate.append(growth)

    print(growth_rate)

    # how does the growth rate itself grow?

    cumulative_per_day = infections_per_day.cumsum()
    elapsed = infections_per_day.index.map(lambda date: (date- day_0).days)

    @@ -54,12 +50,17 @@ def sigmoid(x, L, x0, k):
    y = L / (1 + np.exp(-k*(x-x0)))
    return y

    hypotheses = [
    [300, 20, 0.2],
    [900, 21, 0.3],
    [3000, 25, 0.3],
    [15000, 40, np.mean(growth_rate)],
    ]
    def sigmoid_with_growth(growth):
    return lambda x, L, x0: sigmoid(x, L, x0, growth)


    # fit for various growth rates
    print(cumulative_per_day)
    hypotheses = []
    growth_rates = [0.23, 0.25, 0.27, 0.34]
    for g in growth_rates:
    popt, pcov = curve_fit(sigmoid_with_growth(g), xdata, ydata)
    hypotheses.append([*popt, g])

    # plot each scenario
    # generate x axis over 90 days since Feb 26th
    @@ -69,21 +70,24 @@ def sigmoid(x, L, x0, k):
    midpoint_time = day_0 + datetime.timedelta(days=params[1])
    prediction = params[0] / 2
    y = sigmoid(x, *params)

    # if it exists then check if it's within the expected bounds
    real = df.get(midpoint_time) # TODO: Find the first-datapoint available after midpoint
    if real:
    if abs(real - prediction) < eps:
    print(f"Prediction {params} was within reality")
    pylab.plot(x,y, label=f'{params}')
    else:
    print(f"Bad prediction: {params}")
    else:
    print(f"Expecting to reach {prediction} by {midpoint_time}")
    pylab.plot(x,y, label=f'{params}')
    # ind = midpoint_time
    # for index in cumulative_per_day.index:
    # if index >= midpoint_time:
    # ind = index
    # real = cumulative_per_day.loc[ind]
    # if real is not None:
    # if abs(real - prediction) < eps:
    # print(f"Prediction {params} was within reality")
    # pylab.plot(x,y, label=f'{params}')
    # else:
    # print(f"Bad prediction: {params}")
    # else:
    print(f"Expecting to reach {prediction} by {midpoint_time} ({params[1]} after initial)")
    pylab.plot(x,y, label=f'{params}')

    pylab.xlabel("Days since first incident")
    pylab.xlim([0, 100])
    pylab.ylabel("Number tested positive")
    pylab.legend(loc='best')
    pylab.show()
    pylab.show()
    2 changes: 1 addition & 1 deletion greece.csv
    Original file line number Diff line number Diff line change
    @@ -15,4 +15,4 @@
    09.03.2020 |11| ? | ? | ? | ?
    10.03.2020 |5| ? | ? | ? | ?
    11.03.2020 |10| ? | ? | ? | ?
    12.03.2020 |34| ? | ? |? | https://www.alphafreepress.gr/2020/03/12/ellada/nea-krousmata-koronoios-konta-sta-30-ta-nea-krousmata-stin-ellada/
    12.03.2020 |18| ? | ? |? | https://www.alphafreepress.gr/2020/03/12/ellada/nea-krousmata-koronoios-konta-sta-30-ta-nea-krousmata-stin-ellada/
  2. gakonst revised this gist Mar 12, 2020. No changes.
  3. gakonst revised this gist Mar 12, 2020. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions greece.csv
    Original file line number Diff line number Diff line change
    @@ -15,3 +15,4 @@
    09.03.2020 |11| ? | ? | ? | ?
    10.03.2020 |5| ? | ? | ? | ?
    11.03.2020 |10| ? | ? | ? | ?
    12.03.2020 |34| ? | ? |? | https://www.alphafreepress.gr/2020/03/12/ellada/nea-krousmata-koronoios-konta-sta-30-ta-nea-krousmata-stin-ellada/
  4. gakonst revised this gist Mar 12, 2020. No changes.
  5. gakonst revised this gist Mar 12, 2020. 1 changed file with 18 additions and 3 deletions.
    21 changes: 18 additions & 3 deletions covid19.py
    Original file line number Diff line number Diff line change
    @@ -55,20 +55,35 @@ def sigmoid(x, L, x0, k):
    return y

    hypotheses = [
    # cap out at 300 infected, should reach 150 infected by March 15th
    [300, 20, 0.2],
    # Reach 7500 infected by end of March
    [900, 21, 0.3],
    [3000, 25, 0.3],
    [15000, 40, np.mean(growth_rate)],
    ]

    # plot each scenario
    # generate x axis over 90 days since Feb 26th
    x = np.linspace(0, 90, 100)
    eps = 15
    for params in hypotheses:
    midpoint_time = day_0 + datetime.timedelta(days=params[1])
    prediction = params[0] / 2
    y = sigmoid(x, *params)
    pylab.plot(x,y, label=f'{params}')

    # if it exists then check if it's within the expected bounds
    real = df.get(midpoint_time) # TODO: Find the first-datapoint available after midpoint
    if real:
    if abs(real - prediction) < eps:
    print(f"Prediction {params} was within reality")
    pylab.plot(x,y, label=f'{params}')
    else:
    print(f"Bad prediction: {params}")
    else:
    print(f"Expecting to reach {prediction} by {midpoint_time}")
    pylab.plot(x,y, label=f'{params}')

    pylab.xlabel("Days since first incident")
    pylab.xlim([0, 100])
    pylab.ylabel("Number tested positive")
    pylab.legend(loc='best')
    pylab.show()
  6. gakonst revised this gist Mar 12, 2020. 1 changed file with 31 additions and 15 deletions.
    46 changes: 31 additions & 15 deletions covid19.py
    Original file line number Diff line number Diff line change
    @@ -29,30 +29,46 @@

    ## group all intra day infections together
    infections_per_day = pd.Series(df.groupby(['date']).agg(sum)['infections'])

    # calculate the growth rate of the infections
    growth_rate = []
    for i in range(1, len(infections_per_day)):
    diff = abs(infections_per_day[i] - infections_per_day[i-1])
    growth = diff / infections_per_day[i-1]
    growth_rate.append(growth)

    print(growth_rate)

    # how does the growth rate itself grow?

    cumulative_per_day = infections_per_day.cumsum()
    elapsed = infections_per_day.index.map(lambda date: (date- day_0).days)

    # fit it to the sigmoid (L = 1)
    # plot the actual data
    xdata = np.array(elapsed)
    ydata = np.array(cumulative_per_day)
    pylab.plot(xdata, ydata, 'o', label='data')

    # f(x) = \frac{L}{1 + e^{-k(x-x0)}}
    def sigmoid(x, L, x0, k):
    y = L / (1 + np.exp(-k*(x-x0)))
    return y
    xdata = np.array(elapsed)
    ydata = np.array(cumulative_per_day)
    # [max, midpoint, growth], pcov = curve_fit(sigmoid, xdata, ydata)
    max = 300
    midpoint = 15
    growth = 0.2

    # generate sigmoid based on estimations
    x = np.linspace(0, 100, 100)
    y = sigmoid(x, max, midpoint, growth)
    hypotheses = [
    # cap out at 300 infected, should reach 150 infected by March 15th
    [300, 20, 0.2],
    # Reach 7500 infected by end of March
    [15000, 40, np.mean(growth_rate)],
    ]

    # plot
    pylab.plot(xdata, ydata, 'o', label='data')
    # pylab.xlabel("Days since first incident at {}".format(day_0.days))
    # plot each scenario
    # generate x axis over 90 days since Feb 26th
    x = np.linspace(0, 90, 100)
    for params in hypotheses:
    y = sigmoid(x, *params)
    pylab.plot(x,y, label=f'{params}')

    pylab.xlabel("Days since first incident")
    pylab.ylabel("Number tested positive")
    pylab.plot(x,y, label='fit')
    pylab.ylim(0, 500)
    pylab.legend(loc='best')
    pylab.show()
  7. gakonst created this gist Mar 12, 2020.
    58 changes: 58 additions & 0 deletions covid19.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@
    import pandas as pd
    import matplotlib.pyplot as plt
    import pylab
    from scipy.optimize import curve_fit
    import numpy as np
    import datetime

    # load the data
    names = ["date", "infections", "age", "gender", "area", "source"]
    df = pd.read_csv(
    'greece.csv',
    names=names,
    sep='|',
    keep_date_col=True,
    index_col=[0]) # index by date

    # convert indexes to dates
    df.index = df.index.map(lambda d: datetime.datetime.strptime(d.strip(), "%d.%m.%Y"))

    # Add elapsed days
    day_0 = df.index[0]
    elapsed = df.index.map(lambda date: (date- day_0).days)
    df['elapsed-days'] = elapsed

    # Calculate cumulative infections
    infections = pd.Series(df['infections'])
    cumulative = infections.cumsum()
    df['cumulative-infections'] = cumulative # load it to the dataframe

    ## group all intra day infections together
    infections_per_day = pd.Series(df.groupby(['date']).agg(sum)['infections'])
    cumulative_per_day = infections_per_day.cumsum()
    elapsed = infections_per_day.index.map(lambda date: (date- day_0).days)

    # fit it to the sigmoid (L = 1)
    # f(x) = \frac{L}{1 + e^{-k(x-x0)}}
    def sigmoid(x, L, x0, k):
    y = L / (1 + np.exp(-k*(x-x0)))
    return y
    xdata = np.array(elapsed)
    ydata = np.array(cumulative_per_day)
    # [max, midpoint, growth], pcov = curve_fit(sigmoid, xdata, ydata)
    max = 300
    midpoint = 15
    growth = 0.2

    # generate sigmoid based on estimations
    x = np.linspace(0, 100, 100)
    y = sigmoid(x, max, midpoint, growth)

    # plot
    pylab.plot(xdata, ydata, 'o', label='data')
    # pylab.xlabel("Days since first incident at {}".format(day_0.days))
    pylab.ylabel("Number tested positive")
    pylab.plot(x,y, label='fit')
    pylab.ylim(0, 500)
    pylab.legend(loc='best')
    pylab.show()
    17 changes: 17 additions & 0 deletions greece.csv
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    26.02.2020 | 1 |38| F | Thessaloniki | Καταγράφεται το πρώτο κρούσμα κορωνοϊού στην Ελλάδα. Πρόκειται για 38χρονη από την Θεσσαλονίκη.
    27.02.2020 |1|10| M | Thessaloniki | Ο γιος της 38χρονης από τη Θεσσαλονίκη, ηλικίας 9 ετών, είναι το δεύτερο κρούσμα κορωνοϊού στην Ελλάδα.
    27.02.2020 |1|40| F | Athens | Τρίτο επιβεβαιωμένο κρούσμα στην Ελλάδα, και πρώτο στην Αθήνα. Πρόκειται για 40χρονη τραπεζικό υπάλληλο, η οποία είχε ταξιδέψει στη Βόρεια Ιταλία.
    28.02.2020 |1|36| F | Athens | Επιβεβαιώνεται το τέταρτο κρούσμα κορωνοϊού στην Ελλάδα (και δεύτερο στην Αθήνα). Πρόκειται για 36χρονη γυναίκα που νοσηλεύεται σε καραντίνα στο «Αττικόν».
    29.02.2020 |1|?|F| Thessaloniki | Πέμπτο επιβεβαιωμένο κρούσμα κορωνοϊού στην Ελλάδα και (τρίτο στη Θεσσαλονίκη). Γυναίκα εκπαιδευτικός, φίλη της 38χρονης.
    29.02.2020 |1|0| F || Έκτο επιβεβαιωμένο κρούσμα κορωνοϊού στην Ελλάδα (και τρίτο στην Αθήνα). Επέστρεψε από ταξίδι στη Βόρεια Ιταλία.
    29.02.2020 |1|0| M | Athens | Άνδρας, στενή επαφή (σύμφωνα με πληροφορίες συνάδερφος) της 40χρονης τραπεζικού στην Αθήνα είναι το έβδομο επιβεβαιωμένο κρούσμα κορωνοϊού στην Ελλάδα (και τέταρτο στην Αθήνα).
    04.03.2020 |1|0| F | Thessaloniki | Καταγράφεται το όγδοο επιβεβαιωμένο κρούσμα κορωνοϊού στην Ελλάδα. Πρόκειται για στενή επαφή (σύζυγος) του πέμπτου επιβεβαιωμένου κρούσματος. O φορέας εντοπίστηκε στη Θεσσαλονίκη.
    04.03.2020 |1|66| M | Ileia | Καταγράφεται το ένατο επιβεβαιωμένο κρούσμα κορωνοϊού στην Ελλάδα. Είναι ο 66χρονος από την Ηλεία, που μπαίνει σε καραντίνα στο νοσοκομείο του Ρίου στην Πάτρα.
    04.03.2020 |1|60+| F | Ileia | Η σύζυγός του 66χρονου από την Ηλεία είναι το δέκατο επιβεβαιωμένο κρούσμα κορωνοϊού
    05.03.2020 |21| ? | F | Ileia | Εκτοξεύεται ο αριθμός των κρουσμάτων κορωνοϊού στην Ελλάδα. Ανακοινώνονται 21 νέα κρούσματα (συνολικά 31 κρούσματα), με τον κ. Τσιόδρα να ξεκαθαρίζει ότι «τις επόμενες εβδομάδες αναμένουμε σημαντική αύξηση του αριθμού των κρουσμάτων κορωνοϊού στην Ελλάδα».
    06.03.2020 |14| ? | ? | Israel |    Στους 45 ανέβηκε ο αριθμός των νέων κρουσμάτων στη χώρα μας καθώς άλλοι 14 βρέθηκαν θετικοί στον ιό από αυτούς που ελέγχθηκαν και ήταν στο ταξιδιωτικό γκρουπ που επέστρεψε από το Ισραήλ. Από αυτούς 3 νοσηλεύονται σε σοβαρή κατάσταση.
    07.03.2020 |21| ? | ? | Israel-Egypt | Ο αριθμός των νέων επιβεβαιωμένων κρουσμάτων έφτασε τους 66. Από αυτούς, οι 51 προέρχονται από την επιδημική έξαρση των εκδρομέων σε Ισραήλ και Αίγυπτο (47 μέλη της ταξιδιωτικής ομάδας και 4 επαφές τους).
    08.03.2020 |7| ? | ? | ? | ?
    09.03.2020 |11| ? | ? | ? | ?
    10.03.2020 |5| ? | ? | ? | ?
    11.03.2020 |10| ? | ? | ? | ?