W podobnym żyle do tego Zapytanie, mam numpy.timedelta64
Kolumna w dataframe Pandas. Zgodnie z tym Odpowiedź do wspomnianego pytania, istnieje funkcja pandas.tslib.repr_timedelta64
, która ładnie wyświetla czasową w dni, Godziny: minuty: sekundy. Chciałbym sformatować je tylko w dniach i godzinach.
Więc co mam, to:
def silly_format(hours):
(days, hours) = divmod(hours, 24)
if days > 0 and hours > 0:
str_time = "{0:.0f} d, {1:.0f} h".format(days, hours)
elif days > 0:
str_time = "{0:.0f} d".format(days)
else:
str_time = "{0:.0f} h".format(hours)
return str_time
df["time"].astype("timedelta64[h]").map(silly_format)
Co dostaje mi pożądane wyjście, ale zastanawiałem się, czy istnieje funkcja w numpy
lub pandas
Podobna do datetime.strftime
, która może formatować numpy.timedelta64
zgodnie z odpowiednim ciągiem formatu?
Próbowałem dalej dostosować rozwiązanie Jeffa, ale jest to wolniej niż moja odpowiedź. Oto:
days = time_delta.astype("timedelta64[D]").astype(int)
hours = time_delta.astype("timedelta64[h]").astype(int) % 24
result = days.astype(str)
mask = (days > 0) & (hours > 0)
result[mask] = days.astype(str) + ' d, ' + hours.astype(str) + ' h'
result[(hours > 0) & ~mask] = hours.astype(str) + ' h'
result[(days > 0) & ~mask] = days.astype(str) + ' d'
4 odpowiedzi
Podczas gdy odpowiedzi dostarczane przez @SEBIX i @JEFF pokazują ładny sposób na konwersję Timedeltas do dni i godzin, a @ Rozwiązanie Jeffa w szczególności zachowuje indeks Series
", brakowało im w elastyczności ostatecznego formatowania ciągu . Rozwiązaniem, którego teraz używam:
def delta_format(days, hours):
if days > 0 and hours > 0:
return "{0:.0f} d, {1:.0f} h".format(days, hours)
elif days > 0:
return "{0:.0f} d".format(days)
else:
return "{0:.0f} h".format(hours)
days = time_delta.astype("timedelta64[D]")
hours = time_delta.astype("timedelta64[h]") % 24
return [delta_format(d, h) for (d, h) in izip(days, hours)]
Który dobrze mi odpowiada i wrócę do indeksu, wkładając tę listę w oryginalny DataFrame
.
Oto jak to zrobić w sposób wektorowy.
In [28]: s = pd.to_timedelta(range(5),unit='d') + pd.offsets.Hour(3)
In [29]: s
Out[29]:
0 0 days, 03:00:00
1 1 days, 03:00:00
2 2 days, 03:00:00
3 3 days, 03:00:00
4 4 days, 03:00:00
dtype: timedelta64[ns]
In [30]: days = s.astype('timedelta64[D]').astype(int)
In [31]: hours = s.astype('timedelta64[h]').astype(int)-days*24
In [32]: days
Out[32]:
0 0
1 1
2 2
3 3
4 4
dtype: int64
In [33]: hours
Out[33]:
0 3
1 3
2 3
3 3
4 3
dtype: int64
In [34]: days.astype(str) + ' d, ' + hours.astype(str) + ' h'
Out[34]:
0 0 d, 3 h
1 1 d, 3 h
2 2 d, 3 h
3 3 d, 3 h
4 4 d, 3 h
dtype: object
Jeśli chcesz dokładnie tak, jak OP pozowano:
In [4]: result = days.astype(str) + ' d, ' + hours.astype(str) + ' h'
In [5]: result[days==0] = hours.astype(str) + ' h'
In [6]: result
Out[6]:
0 3 h
1 1 d, 3 h
2 2 d, 3 h
3 3 d, 3 h
4 4 d, 3 h
dtype: object
@ Odpowiedź Midnightera nie działa dla mnie w Pythonie 3, więc oto moja zaktualizowana funkcja:
def delta_format(delta: np.timedelta64) -> str:
days = delta.astype("timedelta64[D]") / np.timedelta64(1, 'D')
hours = int(delta.astype("timedelta64[h]") / np.timedelta64(1, 'h') % 24)
if days > 0 and hours > 0:
return f"{days:.0f} d, {hours:.0f} h"
elif days > 0:
return f"{days:.0f} d"
else:
return f"{hours:.0f} h"
Zasadniczo taki sam, ale z F-Struns i więcej przymusu typu.
Nie wiem, jak to się robi w pandy, ale oto moje numpy-tylko podejście do twojego problemu:
import numpy as np
t = np.array([200487900000000,180787000000000,400287000000000,188487000000000], dtype='timedelta64[ns]')
days = t.astype('timedelta64[D]').astype(np.int32) # gives: array([2, 2, 4, 2], dtype=int32)
hours = t.astype('timedelta64[h]').astype(np.int32)%24 # gives: array([ 7, 2, 15, 4], dtype=int32)
Więc po prostu konwertuję surowe dane do żądanego typu wyjścia (pozwól, aby numpy zrobi), a następnie mamy dwie tablice z danymi i są bezpłatne, aby używać, jak chcemy. Aby grupować je parami, po prostu zrobić:
>>> np.array([days, hours]).T
array([[ 2, 7],
[ 2, 2],
[ 4, 15],
[ 2, 4]], dtype=int32)
Na przykład:
for row in d:
print('%dd %dh' % tuple(row))
Daje:
2d 7h
2d 2h
4d 15h
2d 4h
Podobne pytania
Nowe pytania
python
Python to wielozadaniowy, wielozadaniowy język programowania dynamicznie typowany. Został zaprojektowany tak, aby był szybki do nauczenia się, zrozumienia i użycia oraz wymuszania czystej i jednolitej składni. Należy pamiętać, że Python 2 oficjalnie nie jest obsługiwany od 01-01-2020. Mimo to, w przypadku pytań Pythona specyficznych dla wersji, dodaj znacznik [python-2.7] lub [python-3.x]. Korzystając z wariantu Pythona (np. Jython, PyPy) lub biblioteki (np. Pandas i NumPy), należy umieścić go w tagach.