(Not duplicate / I did my research)

Mi minute-based dataframe tiene este aspecto:

time,                  price_bool,    price_date
2017-01-01 00:00:00,   False, 
2017-01-01 00:01:00,   False, 
2017-01-01 00:02:00,   True,          2017-01-01 00:02:00
2017-01-01 00:03:00,   False, 
2017-01-01 00:04:00,   False, 
2017-01-01 00:05:00,   True,          2017-01-01 00:05:00
....

En este momento es un conjunto de datos minute-based. Quiero group por day por la aparición first de True y saltar a otro day una vez que se encuentre el primer True. Si no hay True en un conjunto de datos minute-based dado, entonces day tendrá 0 en el price_date.

Mi nuevo dataframe debería verse así:

time,                  price_bool,    price_date
2017-01-01 00:00:00,   True,          2017-01-01 00:02:00
2017-01-02 00:00:00,   True,          2017-01-02 00:07:00
2017-01-03 00:00:00,   True,          2017-01-03 02:21:00
2017-01-04 00:00:00,   True,          2017-01-04 01:17:00
....

Este es el conjunto de datos basado en day donde price_bool es True y correspondiente price_date cuando fue el primer True para un day dado

¿Qué hice?

  • Primero intenté eliminar el campo empty
  • Después de eso, intenté groupby('time')

Sin embargo, no funciona.

-1
floss 9 oct. 2019 a las 23:24

3 respuestas

La mejor respuesta

Datos iniciales más simples:

df = pd.DataFrame([
    ["2017-01-01 00:00:00",False,pd.np.nan], 
    ["2017-01-01 00:00:01",True,"2017-01-01 00:00:01"], 
    ["2017-01-01 00:00:02",True,"2017-01-01 00:00:01"],
    ["2017-01-02 00:00:00",False,pd.np.nan], 
], columns=['time','price_bool','price_date'])
df['time'] = df['time'].apply(pd.to_datetime)

Esto debería obtener los datos que muestra en su resultado (tenga en cuenta que esto supone que ya está ordenado en orden cronológico):

res = df[df['price_bool'] == True].groupby(df['time'].dt.date)[['price_bool','price_date']].first().reset_index()

Sin embargo, creo que está diciendo que desea mantener las fechas con price_bool falso y que price_date sea 0 en ese caso. Por lo tanto, deberá volver a agregar las fechas que faltan en res arriba. Aquí hay una opción:

# Get the True data set right.
res = df[df['price_bool'] == True].groupby(df['time'].dt.date)[['price_bool','price_date']].first()
# Add back the missing dates with only False values
res = res.reindex(df['time'].dt.date.unique()).reset_index()
# Fill in the null values.
res = res.fillna({'price_bool':False, 'price_date':0})

Fuera (tenga en cuenta que creé un conjunto de datos de inicio más simple):

        time    price_bool  price_date
0   2017-01-01  True    2017-01-01 00:00:01
1   2017-01-02  False   0
1
it's-yer-boy-chet 9 oct. 2019 a las 20:47

IIUC:

first_true_daily = df.groupby(pd.Grouper(key='time', freq='D'))['price_bool'].idxmax()

df.loc[first_true_daily]
0
Quang Hoang 9 oct. 2019 a las 20:39
df.sort_values('time').sort_values('price_bool', ascending = False).groupby(df['time'].dt.date).first()

Salida con su df proporcionado:

>>> df
time        price_bool
2017-01-01  True

Explicación : desea ordenar por dos columnas: time y price_bool. Este último debe ordenarse a la inversa, ya que desea que True aparezca antes de False. Luego, dado que groupby conserva la ordenación, simplemente puede seleccionar el primer elemento de cada grupo después de agrupar por fecha.

1
Brian Joseph 9 oct. 2019 a las 20:51
58311775