Tengo un marco de datos con proyectos, fechas de inicio y fechas de finalización. Para cada fila me gustaría devolver el número de otros proyectos en proceso cuando comenzó el proyecto. ¿Cómo anidas bucles cuando usas df.apply()
? Intenté usar un bucle for, pero mi marco de datos es grande y lleva demasiado tiempo.
import datetime as dt
data = {'project' :['A', 'B', 'C'],
'pr_start_date':[dt.datetime(2018, 9, 1), dt.datetime(2019, 4, 1), dt.datetime(2019, 6, 8)],
'pr_end_date': [dt.datetime(2019, 6, 15), dt.datetime(2019, 12, 1), dt.datetime(2019, 8, 1)]}
df = pd.DataFrame(data)
def cons_overlap(start):
overlaps = 0
for i in df.index:
other_start = df.loc[i, 'pr_start_date']
other_end = df.loc[i, 'pr_end_date']
if (start > other_start) & (start < other_end):
overlaps += 1
return overlaps
df['overlap'] = df.apply(lambda row: cons_overlap(row['pr_start_date']), axis=1)
Esta es la salida que estoy buscando:
pr pr_start_date pr_end_date overlap
0 A 2018-09-01 2019-06-15 0
1 B 2019-04-01 2019-12-01 1
2 C 2019-06-08 2019-08-01 2
3 respuestas
Le sugiero que aproveche transmisión de numpy :
ends = df.pr_start_date.values < df.pr_end_date.values[:, None]
starts = df.pr_start_date.values > df.pr_start_date.values[:, None]
df['overlap'] = (ends & starts).sum(0)
print(df)
Salida
project pr_start_date pr_end_date overlap
0 A 2018-09-01 2019-06-15 0
1 B 2019-04-01 2019-12-01 1
2 C 2019-06-08 2019-08-01 2
Ambos extremos y comienzos son matrices de 3x3 que son verdaderas cuando se cumple la condición:
# ends
[[ True True True]
[ True True True]
[ True True True]]
# starts
[[False True True]
[False False True]
[False False False]]
Luego encuentre la intersección con el &
lógico y sume a través de las columnas (sum(0)
).
Debería ser más rápido que tu bucle for
Supongo que las filas están ordenadas por la fecha de inicio y verifico los proyectos iniciados anteriormente que aún no se han completado. Df.index.get_loc (r.name) produce el índice de la fila que se está procesando.
df["overlap"]=df.apply(lambda r: df.loc[:df.index.get_loc(r.name),"pr_end_date"].gt(r["pr_start_date"]).sum()-1, axis=1)
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.