Option 1
Utilisation np.core.defchararray.split
après avoir utilisé strftime
Suivi de assign
après avoir utilisé la division du plancher sur le nombre de secondes
pd.DataFrame(
np.core.defchararray.split(s.index.strftime('%H %a')).tolist(),
columns=['hour', 'day']
).assign(minute=(s.dt.seconds // 60).values)
hour day minute
0 22 Tue 27
1 23 Tue 60
2 00 Wed 60
3 01 Wed 32
Option 2
Utilisation d'un dictionnaire dans une liste de compréhension.
Notez que j'utilise les f-strings de Python 3.6.
Dans le cas contraire, utiliser '{:02d}'.format(i.hour)
pd.DataFrame([dict(
hour=f'{i.hour:02d}',
day=i.strftime('%a'),
minute=v.seconds // 60
) for i, v in s.items()])
day hour minute
0 Tue 22 27
1 Tue 23 60
2 Wed 00 60
3 Wed 01 32
Option 3
Et puisque la question de la vitesse a été soulevée, j'ai voulu proposer une autre option qui en tienne compte.
a = np.array('Mon Tue Wed Thu Fri Sat Sun'.split())
pd.DataFrame(dict(
hour=s.index.hour.astype(str).str.zfill(2),
day=a[s.index.weekday],
minute=s.values.astype('timedelta64[m]').astype(int)
))
day hour minute
0 Tue 22 27
1 Tue 23 60
2 Wed 00 60
3 Wed 01 32
Test de temps complet
Remarque : J'ai modifié les fonctions pour m'assurer que les résultats étaient identiques. En particulier, je me suis concentré sur l'ordre des colonnes et Hour
sous la forme d'une chaîne de caractères.
Fonctions
def jez(s):
a = s.index.strftime('%H')
b = s.index.strftime('%a')
c = s.dt.floor('T').dt.total_seconds().div(60).astype(int)
return pd.DataFrame({'hour':a,'day':b,'minute':c.values},
columns=['hour','day','minute'])
def pir1(s):
return pd.DataFrame(
np.core.defchararray.split(s.index.strftime('%H %a')).tolist(),
columns=['hour', 'day']
).assign(minute=(s.dt.seconds // 60).values)
def pir2(s):
return pd.DataFrame([dict(
hour=f'{i.hour:02d}',
day=i.strftime('%a'),
minute=v.seconds // 60
) for i, v in s.items()], columns=['hour', 'day', 'minute'])
def pir3(s):
a = np.array('Mon Tue Wed Thu Fri Sat Sun'.split())
return pd.DataFrame(dict(
hour=s.index.hour.astype(str).str.zfill(2),
day=a[s.index.weekday],
minute=s.values.astype('timedelta64[m]').astype(int)
), columns=['hour', 'day', 'minute'])
Retour Test
res = pd.DataFrame(
np.nan,
[10, 30, 100, 300, 1000, 3000, 10000, 30000],
'jez pir1 pir2 pir3'.split()
)
for i in res.index:
start = pd.to_datetime("2007-02-21 22:32:41", infer_datetime_format=True)
rng = pd.date_range(start.floor('h'), periods=i, freq='h')
end = rng.max() + pd.to_timedelta("01:32:41")
left = pd.Series(rng, index=rng).clip_lower(start)
right = pd.Series(rng + 1, index=rng).clip_upper(end)
s = right - left
for j in res.columns:
stmt = f'{j}(s)'
setp = f'from __main__ import {j}, s'
res.at[i, j] = timeit(stmt, setp, number=100)
Résultats
res.plot(loglog=True)
![enter image description here]()
res.div(res.min(1), 0)
jez pir1 pir2 pir3
10 2.364757 1.922064 1.000000 1.124539
30 1.916160 2.092680 1.129115 1.000000
100 3.039881 3.361606 2.180457 1.000000
300 3.967504 5.025567 3.920143 1.000000
1000 7.106132 9.757840 7.607425 1.000000
3000 10.104004 14.741414 11.957978 1.000000
10000 10.522324 15.318158 13.262373 1.000000
30000 11.804760 16.718153 14.289628 1.000000
Conclusions
Dans le graphique, vous pouvez voir que jez
, pir1
y pir2
sont toutes regroupées lorsqu'elles sont représentées dans l'espace logarithmique. Cela nous indique que leur temps augmente dans le même ordre de grandeur. Cependant, pir3
a une grande séparation et s'agrandit avec des données plus importantes. La complexité temporelle de pir3
est plus petit et indique un avantage beaucoup plus important.
Cela devient plus clair lorsque nous examinons le tableau des multiples. Chaque ligne a une valeur minimale de 1
qui indique le temps le plus rapide. Toutes les autres valeurs de cette ligne sont des multiples du temps nécessaire pour accomplir la même tâche. En d'autres termes, plus la valeur est grande, plus le temps est lent. Plus la valeur est élevée, plus la méthode est lente. Comme vous pouvez le constater, ces multiples sont de plus en plus importants lorsque les données sont plus volumineuses. Cela signifie que l'avantage de pir3
s'améliore de plus en plus.
C'est à cela que ressemble le mieux. Il est inutile de se vanter d'une amélioration de 25 % du temps. À moins de disposer d'améliorations de l'ordre de grandeur, il est inutile d'essayer de convaincre les lecteurs qu'un algorithme ou une approche est "meilleur".