2017-10-04 4 views
1

J'ai un pandas DataFrame en Python avec deux colonnes indiquant les dates de début et de fin. Je veux:Trouve les plages de dates qui incluent le week-end en utilisant les pandas

  • Compte tenu de deux pandas géants série comme début que les dates de fin en entrée ...
  • déterminer, pour chaque paire de dates de début et de fin, si une date entre l'intervalle [début, fin) (c'est-à-dire incluant le début mais excluant la fin) est soit un vendredi ou un samedi ...
  • Sortie d'une série pandas en tant que booléen.
  • La solution devrait être relativement rapide que je travaille avec plus de 2M rangées.

L'ensemble de données ressemble:

start  end 
2013-08-02 2013-08-04 
2014-11-24 2014-11-28 
2013-10-29 2013-10-31 
2013-12-06 2013-12-10 
2014-08-15 2014-08-17 

J'attendrai quelque chose comme:

has_weekend 
TRUE 
FALSE 
FALSE 
TRUE 
TRUE 

Mon approche actuelle est assez lent pour une trame de données qui a près de 2M lignes. Voici le code:

df.apply(lambda x: np.any(np.in1d([d.weekday() for d in pd.date_range(x.start, x.end)],[4,5])), axis=1) 

Toutes les idées?

SOLUTION La solution la plus rapide était une réponse modifiée de

de @Anton VBr
s = df.start.dt.dayofweek 
e = df.end.dt.dayofweek 
dt = (df.end- df.start).dt.days 
has_weekend = (((s >= 4) & (s != 6)) | (e>=5) | ((e < s) & (s != 6)) | (dt >= 6)) 
+0

Le manque de données dans votre question n'aide pas. –

+0

@ cᴏʟᴅsᴘᴇᴇᴅ J'ai ajouté un extrait des données pour plus de clarté. – dandroid

+0

Pour cette entrée, quelle est la valeur attendue? '0, 1, 3, 4'? –

Répondre

2

Je pensais à certains opérateurs logiques et ceux-ci devraient faire, mais ils ne sont pas une amélioration du temps sur la petite J'ai testé

s = df.start.dt.dayofweek 
e = df.end.dt.dayofweek 
(((s >= 4) & (s != 6)) | ((e>=4) & (s != 6)) | (e < s)) 
+0

C'est presque la réponse que je cherchais, mais ça a définitivement accéléré ... alors que ma première solution prenait 15 minutes, votre solution avec les modifications a pris 15 secondes. (Sans les mods il a fallu 450ms mais ne tenait pas compte des longues périodes de temps entre les dates). J'ai posté la réponse dans les éditions juste au cas où. – dandroid

+0

@dandroid Heureux que ça a marché pour vous. Bonne chance! –