Stacked histogram with datetime in matplotlib - python

I am trying to create a stacked histogram with datetime objects, but I get the following error:
TypeError: unorderable types: datetime.datetime() < float()
The code does work when I either convert the objects to timestamps or when I use one range of data (no stacking).
import datetime
import matplotlib.pyplot as plt
data = [[datetime.datetime(2015, 12, 24, 21, 13, 45), datetime.datetime(2015, 12, 30, 23, 37, 8), datetime.datetime(2015, 12, 30, 19, 43, 18), datetime.datetime(2015, 12, 30, 16, 14, 12), datetime.datetime(2015, 12, 30, 11, 32, 8), datetime.datetime(2015, 12, 29, 6, 29, 25), datetime.datetime(2015, 12, 28, 22, 54, 49), datetime.datetime(2015, 12, 28, 18, 41, 50), datetime.datetime(2015, 12, 28, 14, 25, 42), datetime.datetime(2015, 12, 28, 3, 1, 34), datetime.datetime(2015, 12, 27, 21, 10, 20), datetime.datetime(2015, 12, 27, 11, 29, 38), datetime.datetime(2015, 12, 26, 20, 34, 14), datetime.datetime(2015, 12, 26, 16, 58, 47), datetime.datetime(2015, 12, 26, 10, 54, 40), datetime.datetime(2015, 12, 25, 18, 17, 42), datetime.datetime(2015, 12, 24, 15, 44, 58), datetime.datetime(2015, 12, 25, 17, 25, 9), datetime.datetime(2015, 12, 25, 12, 33, 7), datetime.datetime(2015, 12, 30, 19, 26, 15), datetime.datetime(2015, 12, 30, 12, 46, 13), datetime.datetime(2015, 12, 30, 3, 38, 24), datetime.datetime(2015, 12, 25, 21, 11, 59), datetime.datetime(2015, 12, 25, 13, 30, 34), datetime.datetime(2015, 12, 24, 14, 6, 20)], [datetime.datetime(2015, 12, 28, 20, 59, 53), datetime.datetime(2015, 12, 27, 14, 3, 41), datetime.datetime(2015, 12, 26, 9, 37, 17)], [datetime.datetime(2015, 12, 29, 17, 18, 32)], [datetime.datetime(2015, 12, 29, 23, 15, 24)]]
fig, histograms = plt.subplots(5, 1, sharex=True, squeeze=False)
h = histograms[1][0]
h.hist(data, stacked=True)
This is the code without stacking:
import datetime
import matplotlib.pyplot as plt
data = [datetime.datetime(2015, 12, 24, 21, 13, 45), datetime.datetime(2015, 12, 30, 23, 37, 8), datetime.datetime(2015, 12, 30, 19, 43, 18), datetime.datetime(2015, 12, 30, 16, 14, 12), datetime.datetime(2015, 12, 30, 11, 32, 8), datetime.datetime(2015, 12, 29, 6, 29, 25), datetime.datetime(2015, 12, 28, 22, 54, 49), datetime.datetime(2015, 12, 28, 18, 41, 50), datetime.datetime(2015, 12, 28, 14, 25, 42), datetime.datetime(2015, 12, 28, 3, 1, 34), datetime.datetime(2015, 12, 27, 21, 10, 20), datetime.datetime(2015, 12, 27, 11, 29, 38), datetime.datetime(2015, 12, 26, 20, 34, 14), datetime.datetime(2015, 12, 26, 16, 58, 47), datetime.datetime(2015, 12, 26, 10, 54, 40), datetime.datetime(2015, 12, 25, 18, 17, 42), datetime.datetime(2015, 12, 24, 15, 44, 58), datetime.datetime(2015, 12, 25, 17, 25, 9), datetime.datetime(2015, 12, 25, 12, 33, 7), datetime.datetime(2015, 12, 30, 19, 26, 15), datetime.datetime(2015, 12, 30, 12, 46, 13), datetime.datetime(2015, 12, 30, 3, 38, 24), datetime.datetime(2015, 12, 25, 21, 11, 59), datetime.datetime(2015, 12, 25, 13, 30, 34), datetime.datetime(2015, 12, 24, 14, 6, 20), datetime.datetime(2015, 12, 28, 20, 59, 53), datetime.datetime(2015, 12, 27, 14, 3, 41), datetime.datetime(2015, 12, 26, 9, 37, 17), datetime.datetime(2015, 12, 29, 17, 18, 32), datetime.datetime(2015, 12, 29, 23, 15, 24)]
fig, histograms = plt.subplots(5, 1, sharex=True, squeeze=False)
h = histograms[1][0]
h.hist(data, stacked=True)
NOTE:
As per answers, this is considered a bug. For future visitors I have filed a bug report https://github.com/matplotlib/matplotlib/issues/5898 in case you want to track progress

This is a bug, revealed by version 1.5.x supporting histograms of single series of datetime type data. Previous versions of matplotlib would not histogram datetime data whether stacked or not, failing with a similar error that said datetime could not be compared with float.
The Exception is thrown by this line of code. As you can see, that is called only when bin edges are not specified and is trying to find the minimum in the time series (comparing it with np.inf and taking the minimum of those). You can workaround this by specifying bin edges in the call, but then that leads to a further failure as the numpy histogram function called under the hood looks for less than zero width bins.
"Under the hood" when a single list of datetime.datetime objects is passed to the pyplot.hist() function, the data are actually converted to UNIX epoch timestamps (you can guess this from the labels of the x axis). This is not done when the input is a list of lists of datetime.datetime objects.
At that stage, I think we have to call it a bug and you will have to use timestamp as you have already discovered - e.g. h.hist([[t.timestamp() for t in s] for s in data], stacked=True). You can still give the bin labels in date format, even though the actual data being histogrammed are timestamps, thus this should be transparent to the user.
I'll have a look to see whether I can find a nicer workaround / fix and possibly raise an issue on the matplotlib github.
Code that works (matplotlib 1.5.1, Python 3), albeit a bit messy
import datetime
import matplotlib.pyplot as plt
data = [[datetime.datetime(2015, 12, 24, 21, 13, 45), datetime.datetime(2015, 12, 30, 23, 37, 8), datetime.datetime(2015, 12, 30, 19, 43, 18), datetime.datetime(2015, 12, 30, 16, 14, 12), datetime.datetime(2015, 12, 30, 11, 32, 8), datetime.datetime(2015, 12, 29, 6, 29, 25), datetime.datetime(2015, 12, 28, 22, 54, 49), datetime.datetime(2015, 12, 28, 18, 41, 50), datetime.datetime(2015, 12, 28, 14, 25, 42), datetime.datetime(2015, 12, 28, 3, 1, 34), datetime.datetime(2015, 12, 27, 21, 10, 20), datetime.datetime(2015, 12, 27, 11, 29, 38), datetime.datetime(2015, 12, 26, 20, 34, 14), datetime.datetime(2015, 12, 26, 16, 58, 47), datetime.datetime(2015, 12, 26, 10, 54, 40), datetime.datetime(2015, 12, 25, 18, 17, 42), datetime.datetime(2015, 12, 24, 15, 44, 58), datetime.datetime(2015, 12, 25, 17, 25, 9), datetime.datetime(2015, 12, 25, 12, 33, 7), datetime.datetime(2015, 12, 30, 19, 26, 15), datetime.datetime(2015, 12, 30, 12, 46, 13), datetime.datetime(2015, 12, 30, 3, 38, 24), datetime.datetime(2015, 12, 25, 21, 11, 59), datetime.datetime(2015, 12, 25, 13, 30, 34), datetime.datetime(2015, 12, 24, 14, 6, 20)], [datetime.datetime(2015, 12, 28, 20, 59, 53), datetime.datetime(2015, 12, 27, 14, 3, 41), datetime.datetime(2015, 12, 26, 9, 37, 17)], [datetime.datetime(2015, 12, 29, 17, 18, 32)], [datetime.datetime(2015, 12, 29, 23, 15, 24)]]
fig, histograms = plt.subplots(5, 1, sharex=True, squeeze=False)
h = histograms[1][0]
h.hist([[t.timestamp() for t in l] for l in data], stacked=True)
locs, labels = plt.xticks()
plt.xticks(locs,[datetime.datetime.fromtimestamp(t) for t in locs], rotation='vertical')
plt.gcf().subplots_adjust(bottom=0.4)
fig.set_size_inches(4, 15)
plt.show()
Produces

Related

Fitting a datetime.datetime format with curve_fit

I have the code below, my problem is in the format "datetime.datetime", I can't fit it using a Gaussian function.
import numpy as np
import datetime as datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from scipy.optimize import curve_fit
#ydata
Temperature = ([1.05436258e+03, 1.09296819e+03, 1.05145602e+03, 1.05894926e+03,
1.08366115e+03, 1.08066721e+03, 1.04696163e+03, 1.01842441e+03,
1.04944307e+03, 1.06891551e+03, 1.01844764e+03, 1.03511906e+03,
1.02044599e+03, 9.93275818e+02, 1.03741013e+03, 1.00540470e+03,
1.02573646e+03, 9.75301913e+02, 1.00045743e+03, 1.03321562e+03,
1.03731104e+03, 9.68730834e+02, 9.07474634e+02, 9.30465587e+02,
9.98967526e+02, 9.11791887e+02, 9.15951873e+02, 8.29331306e+02,
9.31702088e+02, 8.90075633e+02, 8.30659093e+02, 8.78715978e+02,
8.66238768e+02, 8.97958014e+02, 6.77909787e+02, 2.23437657e-01,
9.40495055e+02, 8.41990924e+02, 8.75391469e+02, 8.98393043e+02,
9.25048353e+02, 9.31445104e+02, 9.04151363e+02, 2.28176362e-01,
9.65550728e+02, 9.16348809e+02, 9.36315168e+02, 9.00445995e+02,
8.87768320e+02, 8.75064126e+02, 8.81480871e+02, 8.78240278e+02,
8.62958271e+02, 8.93813659e+02, 8.83678318e+02, 9.23593998e+02,
9.15524580e+02, 8.77919073e+02, 8.91754242e+02, 9.19274917e+02,
8.62223914e+02, 8.81275387e+02, 8.62331470e+02, 8.69461632e+02,
8.90014577e+02, 9.02656117e+02, 8.74446393e+02, 8.76284046e+02,
8.66751916e+02, 8.54095049e+02, 8.44540741e+02, 8.70263794e+02,
8.66687327e+02, 8.18019291e+02, 8.21875267e+02, 8.13385138e+02,
8.43198211e+02, 8.70558259e+02, 7.94039978e+02, 8.13497634e+02,
8.12217789e+02, 8.01361143e+02, 8.00263045e+02, 7.47101493e+02,
7.35923635e+02, 7.32930255e+02, 7.75930026e+02, 7.83786631e+02,
7.75255742e+02, 7.74938671e+02, 7.04186773e+02, 7.47612911e+02,
7.29315237e+02, 6.94021293e+02, 7.42723487e+02, 7.09890191e+02,
7.60674339e+02, 7.51491228e+02, 7.23875166e+02, 7.41451471e+02,
7.49694410e+02, 7.43337883e+02, 7.00286359e+02, 7.20250078e+02,
7.32189596e+02, 6.93097572e+02, 7.82342462e+02, 7.11995854e+02,
6.84432159e+02, 7.61195087e+02, 7.46725427e+02, 7.44614939e+02,
6.48985204e+02, 6.76023106e+02, 6.89141056e+02, 6.27855922e+02,
7.07298358e+02, 6.52207871e+02, 6.52609278e+02, 6.80525240e+02,
6.89328581e+02, 6.78148423e+02, 7.28229663e+02, 6.91857497e+02,
7.43998987e+02, 6.96885527e+02, 7.33249599e+02, 7.22833678e+02,
7.34832942e+02, 7.19049095e+02, 7.03573908e+02, 7.11151460e+02,
6.89345427e+02, 6.14126253e+02, 4.60412424e+02])
#xdata
time=[datetime.datetime(2015, 11, 7, 18, 14, 24),
datetime.datetime(2015, 11, 7, 18, 19, 12),
datetime.datetime(2015, 11, 7, 18, 23, 9),
datetime.datetime(2015, 11, 7, 18, 26, 38),
datetime.datetime(2015, 11, 7, 18, 29, 55),
datetime.datetime(2015, 11, 7, 18, 32, 52),
datetime.datetime(2015, 11, 7, 18, 35, 36),
datetime.datetime(2015, 11, 7, 18, 38, 26),
datetime.datetime(2015, 11, 7, 18, 41, 13),
datetime.datetime(2015, 11, 7, 18, 44, 16),
datetime.datetime(2015, 11, 7, 18, 47, 12),
datetime.datetime(2015, 11, 7, 18, 50, 1),
datetime.datetime(2015, 11, 7, 18, 53, 2),
datetime.datetime(2015, 11, 7, 18, 56, 17),
datetime.datetime(2015, 11, 7, 18, 59, 45),
datetime.datetime(2015, 11, 7, 19, 3, 14),
datetime.datetime(2015, 11, 7, 19, 6, 28),
datetime.datetime(2015, 11, 7, 19, 10, 4),
datetime.datetime(2015, 11, 7, 19, 13, 46),
datetime.datetime(2015, 11, 7, 19, 17, 47),
datetime.datetime(2015, 11, 7, 19, 21, 35),
datetime.datetime(2015, 11, 7, 19, 25, 15),
datetime.datetime(2015, 11, 7, 19, 29, 22),
datetime.datetime(2015, 11, 7, 19, 33, 41),
datetime.datetime(2015, 11, 7, 19, 38, 38),
datetime.datetime(2015, 11, 7, 19, 43, 16),
datetime.datetime(2015, 11, 7, 19, 47, 53),
datetime.datetime(2015, 11, 7, 19, 53, 21),
datetime.datetime(2015, 11, 7, 19, 59, 4),
datetime.datetime(2015, 11, 7, 20, 5, 14),
datetime.datetime(2015, 11, 7, 20, 11, 6),
datetime.datetime(2015, 11, 7, 20, 17, 7),
datetime.datetime(2015, 11, 7, 20, 24, 11),
datetime.datetime(2015, 11, 7, 20, 31, 5),
datetime.datetime(2015, 11, 7, 20, 38, 1),
datetime.datetime(2015, 11, 7, 20, 44, 39),
datetime.datetime(2015, 11, 7, 20, 50, 8),
datetime.datetime(2015, 11, 7, 20, 54, 31),
datetime.datetime(2015, 11, 7, 20, 59, 28),
datetime.datetime(2015, 11, 7, 21, 4, 54),
datetime.datetime(2015, 11, 7, 21, 10, 24),
datetime.datetime(2015, 11, 7, 21, 15, 56),
datetime.datetime(2015, 11, 7, 21, 21, 50),
datetime.datetime(2015, 11, 7, 21, 27, 38),
datetime.datetime(2015, 11, 7, 21, 33, 24),
datetime.datetime(2015, 11, 7, 21, 37, 54),
datetime.datetime(2015, 11, 7, 21, 42, 24),
datetime.datetime(2015, 11, 7, 21, 47, 20),
datetime.datetime(2015, 11, 7, 21, 52, 12),
datetime.datetime(2015, 11, 7, 21, 57, 3),
datetime.datetime(2015, 11, 7, 22, 1, 41),
datetime.datetime(2015, 11, 7, 22, 6, 21),
datetime.datetime(2015, 11, 7, 22, 11, 30),
datetime.datetime(2015, 11, 7, 22, 16, 44),
datetime.datetime(2015, 11, 7, 22, 21, 59),
datetime.datetime(2015, 11, 7, 22, 26, 56),
datetime.datetime(2015, 11, 7, 22, 32),
datetime.datetime(2015, 11, 7, 22, 37, 43),
datetime.datetime(2015, 11, 7, 22, 43, 21),
datetime.datetime(2015, 11, 7, 22, 48, 45),
datetime.datetime(2015, 11, 7, 22, 53, 49),
datetime.datetime(2015, 11, 7, 22, 58, 49),
datetime.datetime(2015, 11, 7, 23, 4, 4),
datetime.datetime(2015, 11, 7, 23, 9, 8),
datetime.datetime(2015, 11, 7, 23, 14, 3),
datetime.datetime(2015, 11, 7, 23, 18, 34),
datetime.datetime(2015, 11, 7, 23, 22, 58),
datetime.datetime(2015, 11, 7, 23, 27, 43),
datetime.datetime(2015, 11, 7, 23, 32, 22),
datetime.datetime(2015, 11, 7, 23, 36, 48),
datetime.datetime(2015, 11, 7, 23, 41, 9),
datetime.datetime(2015, 11, 7, 23, 45, 29),
datetime.datetime(2015, 11, 7, 23, 49, 59),
datetime.datetime(2015, 11, 7, 23, 54, 34),
datetime.datetime(2015, 11, 7, 23, 59, 6),
datetime.datetime(2015, 11, 8, 0, 3, 37),
datetime.datetime(2015, 11, 8, 0, 8, 17),
datetime.datetime(2015, 11, 8, 0, 13, 15),
datetime.datetime(2015, 11, 8, 0, 18, 22),
datetime.datetime(2015, 11, 8, 0, 23, 23),
datetime.datetime(2015, 11, 8, 0, 28, 28),
datetime.datetime(2015, 11, 8, 0, 33, 59),
datetime.datetime(2015, 11, 8, 0, 39, 51),
datetime.datetime(2015, 11, 8, 0, 45, 56),
datetime.datetime(2015, 11, 8, 0, 51, 57),
datetime.datetime(2015, 11, 8, 0, 57, 48),
datetime.datetime(2015, 11, 8, 1, 4, 2),
datetime.datetime(2015, 11, 8, 1, 10, 47),
datetime.datetime(2015, 11, 8, 1, 17, 43),
datetime.datetime(2015, 11, 8, 1, 24, 22),
datetime.datetime(2015, 11, 8, 1, 30, 39),
datetime.datetime(2015, 11, 8, 1, 37, 2),
datetime.datetime(2015, 11, 8, 1, 43, 51),
datetime.datetime(2015, 11, 8, 1, 50, 38),
datetime.datetime(2015, 11, 8, 1, 57, 23),
datetime.datetime(2015, 11, 8, 2, 4, 3),
datetime.datetime(2015, 11, 8, 2, 10, 46),
datetime.datetime(2015, 11, 8, 2, 18, 6),
datetime.datetime(2015, 11, 8, 2, 25, 14),
datetime.datetime(2015, 11, 8, 2, 32, 30),
datetime.datetime(2015, 11, 8, 2, 39, 35),
datetime.datetime(2015, 11, 8, 2, 46, 49),
datetime.datetime(2015, 11, 8, 2, 54, 43),
datetime.datetime(2015, 11, 8, 3, 2, 33),
datetime.datetime(2015, 11, 8, 3, 10, 15),
datetime.datetime(2015, 11, 8, 3, 17, 28),
datetime.datetime(2015, 11, 8, 3, 24, 30),
datetime.datetime(2015, 11, 8, 3, 32, 8),
datetime.datetime(2015, 11, 8, 3, 39, 13),
datetime.datetime(2015, 11, 8, 3, 46, 10),
datetime.datetime(2015, 11, 8, 3, 52, 48),
datetime.datetime(2015, 11, 8, 3, 59, 1),
datetime.datetime(2015, 11, 8, 4, 5, 39),
datetime.datetime(2015, 11, 8, 4, 11, 59),
datetime.datetime(2015, 11, 8, 4, 18, 27),
datetime.datetime(2015, 11, 8, 4, 24, 49),
datetime.datetime(2015, 11, 8, 4, 31, 7),
datetime.datetime(2015, 11, 8, 4, 39, 18),
datetime.datetime(2015, 11, 8, 4, 46, 26),
datetime.datetime(2015, 11, 8, 4, 53, 13),
datetime.datetime(2015, 11, 8, 5, 0, 11),
datetime.datetime(2015, 11, 8, 5, 8, 57),
datetime.datetime(2015, 11, 8, 5, 15, 45),
datetime.datetime(2015, 11, 8, 5, 22, 6),
datetime.datetime(2015, 11, 8, 5, 28, 5),
datetime.datetime(2015, 11, 8, 5, 34, 57),
datetime.datetime(2015, 11, 8, 5, 40, 4),
datetime.datetime(2015, 11, 8, 5, 44, 45),
datetime.datetime(2015, 11, 8, 5, 49, 8),
datetime.datetime(2015, 11, 8, 5, 54, 41),
datetime.datetime(2015, 11, 8, 5, 58, 46),
datetime.datetime(2015, 11, 8, 6, 2, 35),
datetime.datetime(2015, 11, 8, 6, 6, 18),
datetime.datetime(2015, 11, 8, 6, 11, 11),
datetime.datetime(2015, 11, 8, 6, 14, 45)]
#ploting data
#plt.plot(time, Temperature)
#plt.show()
#curve_fit
def fun(x, A, B) :
return A*np.exp(-1*B*x**2)
parameters, covariance = curve_fit(fun, time, Temperature)
plt.plot(time, fun(time, *parameters))
plt.show()
this is the result of execution it :
Traceback (most recent call last): File "datetime_fit.py", line 187,
in
parameters, covariance = curve_fit(fun, time, Temperature) File "/home/lhoussine/anaconda3/lib/python3.8/site-packages/scipy/optimize/minpack.py",
line 742, in curve_fit
xdata = np.asarray_chkfinite(xdata, float) File "/home/lhoussine/anaconda3/lib/python3.8/site-packages/numpy/lib/function_base.py",
line 486, in asarray_chkfinite
a = asarray(a, dtype=dtype, order=order) TypeError: float() argument must be a string or a number, not 'datetime.datetime'
You'll need to use a numeric representation of date and time, e.g. Unix time which you can obtain from the datetime object's timestamp method. Ex:
def fun(x, A, B) :
return A*x + B # a simple linear fit for illustration
ts = np.array([t.timestamp() for t in time])
parameters, covariance = curve_fit(fun, ts, Temperature)
plt.plot(time, Temperature)
plt.plot(time, fun(ts, *parameters))
plt.show()

How can I replace datetime with While loop in Python

from datetime import datetime
from datetime import timedelta
dateIs = datetime.today()
thisDay = datetime.strftime(dateIs, "%d")
thisDayInt = int(thisDay)
dateListTest = []
if(thisDayInt > 0):
while thisDayInt > 1:
thisDayInt -= 1
dateIs.replace(day=thisDayInt,hour=0,minute=0,second=0)
dateListTest.append(dateIs)
print(dateListTest)
Output
[datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371),
datetime.datetime(2021, 11, 18, 23, 38, 23, 687371)]
What I want to do in this part is to get a list of the days from today to the beginning of the month one by one, but when I put them in the While loop, I cannot print the days by decrement. I don't know about a shorter path or where I'm skipping.
List comprehension
You could use a list comprehension for this.
from datetime import datetime
dateIs = datetime.today().replace(hour=0, minute=0, second=0, microsecond=0)
thisDay = dateIs.day
dateListTest = [dateIs.replace(day=d) for d in range(thisDay-1, 0, -1)]
print(dateListTest)
[datetime.datetime(2021, 11, 17, 0, 0),
datetime.datetime(2021, 11, 16, 0, 0),
datetime.datetime(2021, 11, 15, 0, 0),
datetime.datetime(2021, 11, 14, 0, 0),
datetime.datetime(2021, 11, 13, 0, 0),
datetime.datetime(2021, 11, 12, 0, 0),
datetime.datetime(2021, 11, 11, 0, 0),
datetime.datetime(2021, 11, 10, 0, 0),
datetime.datetime(2021, 11, 9, 0, 0),
datetime.datetime(2021, 11, 8, 0, 0),
datetime.datetime(2021, 11, 7, 0, 0),
datetime.datetime(2021, 11, 6, 0, 0),
datetime.datetime(2021, 11, 5, 0, 0),
datetime.datetime(2021, 11, 4, 0, 0),
datetime.datetime(2021, 11, 3, 0, 0),
datetime.datetime(2021, 11, 2, 0, 0),
datetime.datetime(2021, 11, 1, 0, 0)]
Pandas
You could also do it with date_range from Pandas, though you will end up with a list of datetime.date rather than datetime.datetime.
from datetime import datetime
import pandas as pd
dateIs = datetime.today().replace(hour=0, minute=0, second=0, microsecond=0)
thisDay = dateIs.day
dateListTestPandas =pd.date_range(start=dateIs.replace(day=thisDay-1), end=dateIs.replace(day=1), freq="-1D").date.tolist()
print(dateListTestPandas)
[datetime.date(2021, 11, 17),
datetime.date(2021, 11, 16),
datetime.date(2021, 11, 15),
datetime.date(2021, 11, 14),
datetime.date(2021, 11, 13),
datetime.date(2021, 11, 12),
datetime.date(2021, 11, 11),
datetime.date(2021, 11, 10),
datetime.date(2021, 11, 9),
datetime.date(2021, 11, 8),
datetime.date(2021, 11, 7),
datetime.date(2021, 11, 6),
datetime.date(2021, 11, 5),
datetime.date(2021, 11, 4),
datetime.date(2021, 11, 3),
datetime.date(2021, 11, 2),
datetime.date(2021, 11, 1)]

Group elements with same date in list in python in python [duplicate]

This question already has answers here:
Python List Group by Date
(2 answers)
Closed 3 years ago.
I have this list :
list = [datetime.datetime(2019, 10, 20, 16, 37), datetime.datetime(2019, 10, 20, 16, 50, 7), datetime.datetime(2019, 11, 21, 16, 51, 47), datetime.datetime(2019, 11, 21, 10, 51, 20), datetime.datetime(2019, 10, 21, 10, 53, 22), datetime.datetime(2019, 11, 21, 10, 58, 27)]
I want to group elements with same date in list , how to do this please ?
[datetime.datetime(2019, 10, 20, 16, 37) , datetime.datetime(2019, 10, 20, 16, 50, 7) ]
[datetime.datetime(2019, 10, 21, 10, 53, 22)]
[datetime.datetime(2019, 11, 21, 16, 51, 47), datetime.datetime(2019, 11, 21, 10, 51, 20),datetime.datetime(2019, 11, 21, 10, 58, 27)]
Use itertools.groupby:
from itertools import groupby
f = lambda x:x.date()
[[i for i in g] for k, g in groupby(sorted(l, key=f), key=f)]
Output:
[[datetime.datetime(2019, 10, 20, 16, 37),
datetime.datetime(2019, 10, 20, 16, 50, 7)],
[datetime.datetime(2019, 10, 21, 10, 53, 22)],
[datetime.datetime(2019, 11, 21, 16, 51, 47),
datetime.datetime(2019, 11, 21, 10, 51, 20),
datetime.datetime(2019, 11, 21, 10, 58, 27)]]
You could just use itertools.groupby like,
>>> import itertools
>>> import datetime
>>> x
[datetime.datetime(2019, 10, 20, 16, 37), datetime.datetime(2019, 10, 20, 16, 50, 7), datetime.datetime(2019, 11, 21, 16, 51, 47), datetime.datetime(2019, 11, 21, 10, 51, 20), datetime.datetime(2019, 10, 21, 10, 53, 22), datetime.datetime(2019, 11, 21, 10, 58, 27)]
>>> s = [list(v) for k,v in itertools.groupby(sorted(x), lambda x: (x.year, x.month, x.day))]
>>>
>>>
>>> pprint.pprint(s)
[[datetime.datetime(2019, 10, 20, 16, 37),
datetime.datetime(2019, 10, 20, 16, 50, 7)],
[datetime.datetime(2019, 10, 21, 10, 53, 22)],
[datetime.datetime(2019, 11, 21, 10, 51, 20),
datetime.datetime(2019, 11, 21, 10, 58, 27),
datetime.datetime(2019, 11, 21, 16, 51, 47)]]
>>>
Using dict.setdefault and a simple iteration.
Ex:
import datetime
data = [datetime.datetime(2019, 10, 20, 16, 37), datetime.datetime(2019, 10, 20, 16, 50, 7), datetime.datetime(2019, 11, 21, 16, 51, 47), datetime.datetime(2019, 11, 21, 10, 51, 20), datetime.datetime(2019, 10, 21, 10, 53, 22), datetime.datetime(2019, 11, 21, 10, 58, 27)]
result = {}
for i in data:
result.setdefault(i.strftime("%Y%m%d"), []).append(i)
print(list(result.values()))
Output:
[[datetime.datetime(2019, 10, 20, 16, 37),
datetime.datetime(2019, 10, 20, 16, 50, 7)],
[datetime.datetime(2019, 11, 21, 16, 51, 47),
datetime.datetime(2019, 11, 21, 10, 51, 20),
datetime.datetime(2019, 11, 21, 10, 58, 27)],
[datetime.datetime(2019, 10, 21, 10, 53, 22)]]

Convert datetime.datetime to day of the week, and then plot

I have a list of datetime.datetime objects:
x1 = [
datetime.datetime(2019, 8, 18, 21, 21, 23),
datetime.datetime(2019, 8, 18, 20, 38, 6),
datetime.datetime(2019, 8, 18, 18, 45, 38),
datetime.datetime(2019, 8, 18, 15, 35, 25),
datetime.datetime(2019, 8, 18, 15, 29, 54),
datetime.datetime(2019, 8, 18, 15, 26, 19)
]
And I would like to extract the day of the week they are (0 Monday, 6 Sunday, for example), and then plot 7 histogram, one per day, with the hours in the x axis.
So far no luck using .weekday()
What you have is something like this basically, note that I have two dates here 18th August and 21st August, so two weekdays (I will not do for 7 but the logic remains the same):
x1 = [datetime.datetime(2019, 8, 18, 21, 21, 23),
datetime.datetime(2019, 8, 18, 20, 38, 6),
datetime.datetime(2019, 8, 18, 18, 45, 38),
datetime.datetime(2019, 8, 18, 15, 35, 25),
datetime.datetime(2019, 8, 18, 15, 29, 54),
datetime.datetime(2019, 8, 18, 15, 26, 19),
datetime.datetime(2019, 8, 21, 21, 21, 23),
datetime.datetime(2019, 8, 21, 21, 38, 6),
datetime.datetime(2019, 8, 21, 18, 45, 38),
datetime.datetime(2019, 8, 21, 16, 35, 25),
datetime.datetime(2019, 8, 21, 16, 29, 54),
datetime.datetime(2019, 8, 21, 15, 26, 19)]
Solution:
First get all your records, hours and weekdays to a pandas dataframe:
import pandas as pd
day, hour = [], []
for x in x1:
day.append(x.weekday())
hour.append(x.hour)
df = pd.DataFrame()
df['day'] = day
df['hour'] = hour
Get the number of different days for which you have data (in your case, it will be 7, my case it is 2 from the example):
dayList = df['day'].unique().tolist()
Now plot them in a loop:
import matplotlib.pyplot as plt
for i in dayList:
tempDf = df.copy()
tempDf = tempDf[tempDf['day'] == i]
tempDf['hour'].plot(kind='hist', title='Plot for day' + str(i))
plt.show()
You will see two graphs (in your case it should be 7 graphs, one for each day) for the example I have given, it count the number of times different hours have records:
Maybe this is what you asked
import matplotlib.pyplot as plt
import datetime
import numpy as np
x1 = [datetime.datetime(2019, 8, 18, 21, 21, 23),
datetime.datetime(2019, 8, 18, 20, 38, 6),
datetime.datetime(2019, 8, 18, 18, 45, 38),
datetime.datetime(2019, 8, 18, 15, 35, 25),
datetime.datetime(2019, 8, 18, 15, 29, 54),
datetime.datetime(2019, 8, 18, 15, 26, 19)]
day, hours = [], []
for i in x1:
day.append(i.weekday())
hours.append(i.hour)
data = np.column_stack((hours, day))
plt.hist(data, density=1, facecolor='blue', alpha=0.8)
plt.ylabel('Day')
plt.xlabel('Hours')
plt.show()
I can understand your question very vaguely, because I'm a newbie and couldn't think much without an example of your need. For now I think this might be helpful:
days = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
x1 = [datetime.datetime(2019, 8, 18, 21, 21, 23),
datetime.datetime(2019, 8, 18, 20, 38, 6),
datetime.datetime(2019, 8, 18, 18, 45, 38),
datetime.datetime(2019, 8, 18, 15, 35, 25),
datetime.datetime(2019, 8, 18, 15, 29, 54),
datetime.datetime(2019, 8, 18, 15, 26, 19)]
for i in x1:
print(days[i.weekday()]) #This will print the day of the week with respect to the date
And using .hour attribute of datetime object you can get the hour.

Sorting datetime object in a list of tuples [duplicate]

This question already has answers here:
How to sort a list of lists by a specific index of the inner list?
(12 answers)
Closed 4 years ago.
i have a list of tuples which is like following
[('John', datetime.datetime(2016, 11, 27, 18, 18), datetime.datetime(2017, 11, 27, 18, 18)), ('Adam', datetime.datetime(2017, 11, 27, 18, 18), datetime.datetime(2018, 11, 27, 18, 18), ('Adam', datetime.datetime(2001, 05, 27, 18, 18), datetime.datetime(2002, 09, 27, 18, 18)) ('Adam', datetime.datetime(2015, 11, 27, 18, 18), datetime.datetime(2016, 11, 27, 18, 18))]
How can i sort this list based on the datetime object, basically its in the format Name,From date, To date
Just use the key parameter of sorted on from_date:
import datetime
data = [('John', datetime.datetime(2016, 11, 27, 18, 18), datetime.datetime(2017, 11, 27, 18, 18)),
('Adam', datetime.datetime(2017, 11, 27, 18, 18), datetime.datetime(2018, 11, 27, 18, 18)),
('Adam', datetime.datetime(2001, 5, 27, 18, 18), datetime.datetime(2002, 9, 27, 18, 18)),
('Adam', datetime.datetime(2015, 11, 27, 18, 18), datetime.datetime(2016, 11, 27, 18, 18))]
result = sorted(data, key=lambda x: x[1])
for e in result:
print(e)
Output
('Adam', datetime.datetime(2001, 5, 27, 18, 18), datetime.datetime(2002, 9, 27, 18, 18))
('Adam', datetime.datetime(2015, 11, 27, 18, 18), datetime.datetime(2016, 11, 27, 18, 18))
('John', datetime.datetime(2016, 11, 27, 18, 18), datetime.datetime(2017, 11, 27, 18, 18))
('Adam', datetime.datetime(2017, 11, 27, 18, 18), datetime.datetime(2018, 11, 27, 18, 18))
I'm not sure if I got the question right. But, I think you're looking for something like this:
sorted(a, key=lambda x: x[1])
Since you can compare DateTime objects with each other, the only thing remaining to do is to ask the sorted function to sort based on them (in this case the second element of each tuple).

Categories

Resources