Разница во времени между периодом времени и мгновенным 1 - PullRequest
1 голос
/ 05 марта 2019

У меня есть несколько моментов времени (A, B) и несколько периодов времени (CD).Я хотел бы найти разницу во времени между каждым периодом времени и соответствующим ему моментом времени.Я имею в виду, что:

, если время (A или B) находится между C и D

, то dT = 0

Я пытался сделать это так:

df = pd.DataFrame({'A': [dt.datetime(2017,1,6),      dt.datetime(2017,1,4)],
                   'B': [dt.datetime(2017,1,7),      dt.datetime(2017,1,5)],
                   'C': [dt.datetime(2017,1,6,12,3), dt.datetime(2017,1,6,13,3)],
                   'D': [dt.datetime(2017,1,8,12,3), dt.datetime(2017,1,8,14,3)]})

# Calculate the time difference
def dT(Time, on, off):
    if Time < on:
        return on - Time
    elif Time > off:
        return Time - off
    else:
        return 0
dT = np.vectorize(dT)

df['dT_A'] = dT(df['A'], df['C'], df['D'])
df['dT_B'] = dT(df['B'], df['C'], df['D'])

# Change the time difference to a float
def floa(dT):
    if dT == 0:
        return 0
    else:
        return dT / timedelta (days=1)
floa = np.vectorize(floa)

df['dT_A'] = floa(df['dT_A'])
df['dT_B'] = floa(df['dT_B'])

Он рассчитал dt_A, но затем дал мне эту ошибку:

OverflowError: Python int too large to convert to C long

Ответы [ 2 ]

2 голосов
/ 05 марта 2019

Несмотря на название, np.vectorize не векторизовано - оно работает в циклах. Так что лучше работать с векторами, если вы можете, и, к счастью, то, что вы хотите, довольно легко сделать в «ванильных» пандах:

import datetime as dt

df = pd.DataFrame({'A': [dt.datetime(2017,1,6),      dt.datetime(2017,1,4)],
                   'B': [dt.datetime(2017,1,7),      dt.datetime(2017,1,5)],
                   'C': [dt.datetime(2017,1,6,12,3), dt.datetime(2017,1,6,13,3)],
                   'D': [dt.datetime(2017,1,8,12,3), dt.datetime(2017,1,8,14,3)]})
# default is 0
df['dT_A'] = 0
df['dT_B'] = 0

df.loc[df.A < df.C, 'dT_A'] = (df.C - df.A) .loc[df.A < df.C]
df.loc[df.A > df.D, 'dT_A'] = (df.A - df.D) .loc[df.A > df.D]

df.loc[df.B < df.C, 'dT_B'] = (df.C - df.B) .loc[df.B < df.C]
df.loc[df.B > df.D, 'dT_B'] = (df.B - df.D) .loc[df.B > df.D]

# convert timedelta to number of days, to float
df['dT_A'] = df.dT_A / dt.timedelta(days=1)
df['dT_B'] = df.dT_B / dt.timedelta(days=1)
0 голосов
/ 20 марта 2019

Ответ Джоша (метод А) работает на моем компьютере, однако не работает на компьютере моего коллеги.На компьютере моего коллеги нам нужно было использовать другой loc (метод B).Мой коллега утверждал, что метод А пытался поместить весь столбец в каждую строку.Метод B работает для меня и для моего коллеги, поэтому я отредактирую ответ Джоша на это.

Метод A

import datetime as dt

df = pd.DataFrame({'A': [dt.datetime(2017,1,6),      dt.datetime(2017,1,4)],
                   'B': [dt.datetime(2017,1,7),      dt.datetime(2017,1,5)],
                   'C': [dt.datetime(2017,1,6,12,3), dt.datetime(2017,1,6,13,3)],
                   'D': [dt.datetime(2017,1,8,12,3), dt.datetime(2017,1,8,14,3)]})
# default is 0
df['dT_A'] = 0
df['dT_B'] = 0

df.loc[df.A < df.C, 'dT_A'] = df.C - df.A
df.loc[df.A > df.D, 'dT_A'] = df.A - df.D

df.loc[df.B < df.C, 'dT_B'] = df.C - df.B
df.loc[df.B > df.D, 'dT_B'] = df.B - df.D

# convert timedelta to number of days, to float
df['dT_A'] = df.dT_A / dt.timedelta(days=1)
df['dT_B'] = df.dT_B / dt.timedelta(days=1)

Метод B

import datetime as dt

df = pd.DataFrame({'A': [dt.datetime(2017,1,6),      dt.datetime(2017,1,4)],
                   'B': [dt.datetime(2017,1,7),      dt.datetime(2017,1,5)],
                   'C': [dt.datetime(2017,1,6,12,3), dt.datetime(2017,1,6,13,3)],
                   'D': [dt.datetime(2017,1,8,12,3), dt.datetime(2017,1,8,14,3)]})

# default is 0
df['dT_A'] = 0
df['dT_B'] = 0

df.loc[df.A < df.C, 'dT_A'] = (df.C - df.A) .loc[df.A < df.C]
df.loc[df.A > df.D, 'dT_A'] = (df.A - df.D) .loc[df.A > df.D]

df.loc[df.B < df.C, 'dT_B'] = (df.C - df.B) .loc[df.B < df.C]
df.loc[df.B > df.D, 'dT_B'] = (df.B - df.D) .loc[df.B > df.D]

# Convert timedelta to float, number of days
df['dT_A'] = df.dT_A / np.timedelta64(1, 'D')
df['dT_B'] = df.dT_B / np.timedelta64(1, 'D')
...