Pandas DataFrame Zaman Farkını Saat ve Dakika Olarak İki Sütun Arasındaki Fark


85

Ben iki sütun var, fromdateve todatebir dataframe içinde.

import pandas as pd

data = {'todate': [pd.Timestamp('2014-01-24 13:03:12.050000'), pd.Timestamp('2014-01-27 11:57:18.240000'), pd.Timestamp('2014-01-23 10:07:47.660000')],
        'fromdate': [pd.Timestamp('2014-01-26 23:41:21.870000'), pd.Timestamp('2014-01-27 15:38:22.540000'), pd.Timestamp('2014-01-23 18:50:41.420000')]}

df = pd.DataFrame(data)

diffKullanarak iki tarih arasındaki farkı bulmak için yeni bir sütun ekliyorum

df['diff'] = df['fromdate'] - df['todate']

diffSütunu aldım , ama days24 saatten fazla olduğunda içeriyor .

                   todate                fromdate                   diff
0 2014-01-24 13:03:12.050 2014-01-26 23:41:21.870 2 days 10:38:09.820000
1 2014-01-27 11:57:18.240 2014-01-27 15:38:22.540 0 days 03:41:04.300000
2 2014-01-23 10:07:47.660 2014-01-23 18:50:41.420 0 days 08:42:53.760000

Sonuçlarımı yalnızca saat ve dakikalara nasıl dönüştürebilirim (yani günler saate dönüştürülür)?

Yanıtlar:


127

Pandalar zaman damgası farklılıkları bir datetime.timedelta nesnesi döndürür. Bu, * as_type * yöntemi kullanılarak kolayca saate dönüştürülebilir, örneğin

import pandas
df = pandas.DataFrame(columns=['to','fr','ans'])
df.to = [pandas.Timestamp('2014-01-24 13:03:12.050000'), pandas.Timestamp('2014-01-27 11:57:18.240000'), pandas.Timestamp('2014-01-23 10:07:47.660000')]
df.fr = [pandas.Timestamp('2014-01-26 23:41:21.870000'), pandas.Timestamp('2014-01-27 15:38:22.540000'), pandas.Timestamp('2014-01-23 18:50:41.420000')]
(df.fr-df.to).astype('timedelta64[h]')

pes etmek,

0    58
1     3
2     8
dtype: float64

Astype geçici çözümü işe yarıyor, ancak büyük (0,5 Milyon satır) dosyalar için çok yavaş. Başka öneriniz var mı?
öğrenci1

3
timedelta nesnesi günler ve saniyeler için özniteliklere sahiptir ... siz yapın, (df.fr-df.to) .dt.days * 24 + (df.fr-df.to) .dt.seconds / 3600
nitin

1
Teşekkür ederim! Bu, yılları hesaplamak için (yaşı almak için) benim için de çalıştı: df ['yaş'] = (df ['later_date'] - df ['doğum_tarihi']). Astype ('timedelta64 [Y]')
Superduper

49

.astype()Yukarıdaki çözüm benim için işe yaramadığı için bu beni deli ediyordu . Ama başka bir yol buldum. Zamanlamadım ya da herhangi bir şey, ama orada başkaları için işe yarayabilir

t1 = pd.to_datetime('1/1/2015 01:00')
t2 = pd.to_datetime('1/1/2015 03:30')

print pd.Timedelta(t2 - t1).seconds / 3600.0

... saatler istiyorsanız. Veya:

print pd.Timedelta(t2 - t1).seconds / 60.0

... eğer dakika istiyorsan.


9
Bende de aynı sorun vardı, ancak çözümünüze dikkat etmeniz gerekiyor çünkü bir günden daha büyük saat farkları göz ardı edildiğinden ve ayrı ayrı dahil edilmeleri gerekiyor
nalı

41
Bunun .total_seconds()ihtiyacı olanlar için işe yaradığını yeni buldum
at nalı

İlginç (Ben 4 yıl sonra fark ediyorum) kullanarak, parens kullanmak zorunda ()için .total_seconds()değil.seconds
elPastor

5
  • Sonuçlarımı yalnızca saatlere ve dakikalara nasıl dönüştürebilirim
    • Kabul edilen cevap yalnızca geri döner days + hours. Tutanaklar dahil değildir.
  • Olarak, saat ve dakika sahip bir sütunu sağlamak hh:mmveya x hours y minutesek hesaplamalar ve dize biçimlendirme gerektirir.
  • Bu cevap, timedeltamatematik kullanarak toplam saati veya toplam dakikayı bir kayan nokta olarak nasıl elde edeceğinizi gösterir ve kullanmaktan daha hızlıdır..astype('timedelta64[h]')
  • Pandas Time Deltas Kullanım Kılavuzu
  • Pandas Zaman serisi / tarih işlevi Kullanım Kılavuzu
  • python timedeltanesneleri : Desteklenen işlemlere bakın.
import pandas as pd

# test data from OP, with values already in a datetime format
data = {'to_date': [pd.Timestamp('2014-01-24 13:03:12.050000'), pd.Timestamp('2014-01-27 11:57:18.240000'), pd.Timestamp('2014-01-23 10:07:47.660000')],
        'from_date': [pd.Timestamp('2014-01-26 23:41:21.870000'), pd.Timestamp('2014-01-27 15:38:22.540000'), pd.Timestamp('2014-01-23 18:50:41.420000')]}

# test dataframe; the columns must be in a datetime format; use pandas.to_datetime if needed
df = pd.DataFrame(data)

# add a timedelta column if wanted. It's added here for information only
# df['time_delta_with_sub'] = df.from_date.sub(df.to_date)  # also works
df['time_delta'] = (df.from_date - df.to_date)

# create a column with timedelta as total hours, as a float type
df['tot_hour_diff'] = (df.from_date - df.to_date) / pd.Timedelta(hours=1)

# create a colume with timedelta as total minutes, as a float type
df['tot_mins_diff'] = (df.from_date - df.to_date) / pd.Timedelta(minutes=1)

# display(df)
                  to_date               from_date             time_delta  tot_hour_diff  tot_mins_diff
0 2014-01-24 13:03:12.050 2014-01-26 23:41:21.870 2 days 10:38:09.820000      58.636061    3518.163667
1 2014-01-27 11:57:18.240 2014-01-27 15:38:22.540 0 days 03:41:04.300000       3.684528     221.071667
2 2014-01-23 10:07:47.660 2014-01-23 18:50:41.420 0 days 08:42:53.760000       8.714933     522.896000

Diğer yöntemler

  • Diğer Kaynaklar'daki podcast'ten bir not öğesi .total_seconds(), çekirdek geliştirici tatildeyken eklendi ve birleştirildi ve onaylanmayacaktı.
    • Bu aynı zamanda başka .total_xxyöntemlerin olmamasının da sebebidir .
# convert the entire timedelta to seconds
# this is the same as td / timedelta(seconds=1)
(df.from_date - df.to_date).dt.total_seconds()
[out]:
0    211089.82
1     13264.30
2     31373.76
dtype: float64

# get the number of days
(df.from_date - df.to_date).dt.days
[out]:
0    2
1    0
2    0
dtype: int64

# get the seconds for hours + minutes + seconds, but not days
# note the difference from total_seconds
(df.from_date - df.to_date).dt.seconds
[out]:
0    38289
1    13264
2    31373
dtype: int64

Diğer kaynaklar

%%timeit Ölçek

import pandas as pd

# dataframe with 2M rows
data = {'to_date': [pd.Timestamp('2014-01-24 13:03:12.050000'), pd.Timestamp('2014-01-27 11:57:18.240000')], 'from_date': [pd.Timestamp('2014-01-26 23:41:21.870000'), pd.Timestamp('2014-01-27 15:38:22.540000')]}
df = pd.DataFrame(data)
df = pd.concat([df] * 1000000).reset_index(drop=True)

%%timeit
(df.from_date - df.to_date) / pd.Timedelta(hours=1)
[out]:
43.1 ms ± 1.05 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
(df.from_date - df.to_date).astype('timedelta64[h]')
[out]:
59.8 ms ± 1.29 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.