I have several numpy timedelta values.
I want to convert them to the a format that is better to read for humans without losing information.
Let's say I have td = np.timedelta64(10800000000001, 'ns')
.
Then I can only have it in ns
because if I convert it to ms
or higher it will lose information.
If I have td = np.timedelta64(1080000000000, 'ns')
I can convert it to 3 hours
without losing information.
What is a good way to do this automatically?
I tried it by taking the number of trailing zeros into account:
import numpy as np
if __name__ == "__main__":
td = np.timedelta64(10800000000001, 'ns')
number_of_zeros = len(str(td.item())) - len(str(td.item()).rstrip('0'))
if number_of_zeros==0:
print("[ns]")
elif number_of_zeros<7:
print("ms")
elif number_of_zeros<10:
print("s")
elif number_of_zeros<12:
print("min")
else:
print("h")
This is probably not a very elegant way to do it (not to mention that it will be wrong when we get to minutes and higher). Any recommendations?
If I understand the problem statement, you only want to express the time in terms of one unit: the largest that retains precision using only whole numbers.
import numpy as np
td = np.timedelta64(10800000000000, 'ns')
units = ['h', 'm', 's', 'ms', 'ns']
# Convert to each of the desired units
deltas = [td.astype(f'timedelta64[{unit}]') for unit in units]
# Retain only the ones that are equivalent to the original representation
delta = [delta for delta in deltas if delta == td]
delta[0] # extract the zeroth
# np.timedelta64(3,'h')
It it a little faster to divide the integer representation of the timedelta by the the number of nanoseconds in each unit and check whether the result is a whole number.
# Check whether the number of nanoseconds in each unit is a whole number
divisible = np.divmod(td.astype(int), ns_per_unit)[1] == 0
# Use the first unit for which this is true
unit = units[np.where(divisible)[0][0]]
td.astype(f'timedelta64[{unit}]') # perform the conversion
But the first bit of code is probably a little easier to interpret. Depends on what your goals are.