Python - Panda - Inserisci un valore singolo su una riga per data

Oct 09 2020

Devo creare una colonna, per ogni intervallo di 24 ore, il primo record di data dovrebbe contenere il valore massimo di df.score.

Quindi la nuova colonna, daily_max_scoredovrebbe contenere df.score.max()solo una volta (sul primo record giornaliero, di solito alle 00:00:00, ma non sempre a quell'ora e minuto).

importa i panda come pd

df = pd.DataFrame({
    'date': ['2019-04-19 23:00:00','2019-04-20 00:00:00','2019-04-20 01:00:00', '2019-04-05 08:00:00',
             '2019-07-31 23:30:00','2019-08-01 00:00:00','2019-08-01 01:00:00', '2019-08-01 02:00:00'],
    'ID': ['ID F', 'ID F', 'ID F', 'ID F',
             'ID B', 'ID B', 'ID B', 'ID B'],
    'score': ['50', '100', '99', '99',
             '75', '25', '25', '80']})

df['date'] = pd.to_datetime(df['date'], infer_datetime_format=True)

df

date    ID  score
0   2019-04-19 23:00:00 ID F    50
1   2019-04-20 00:00:00 ID F    100
2   2019-04-20 01:00:00 ID F    99
3   2019-04-05 08:00:00 ID F    99
4   2019-07-31 23:30:00 ID B    75
5   2019-08-01 00:00:00 ID B    25
6   2019-08-01 01:00:00 ID B    25
7   2019-08-01 02:00:00 ID B    80

DataFrame desiderato:

date                    ID      score   daily_max_score
0   2019-04-19 23:00:00 ID F    50      50
1   2019-04-20 00:00:00 ID F    100     100
2   2019-04-20 01:00:00 ID F    99      NaN
3   2019-04-05 08:00:00 ID F    99      99
4   2019-07-31 23:30:00 ID B    75      75
5   2019-08-01 00:00:00 ID B    25      80
6   2019-08-01 01:00:00 ID B    25      NaN
7   2019-08-01 02:00:00 ID B    80      NaN

Risposte

1 Alexander Oct 09 2020 at 02:40

Innanzitutto, converti i valori della data del testo in datetimes effettivi tramite df['date'] = pd.to_datetime(df['date']).

Quindi raggruppa nelle date tramite df.groupby(df['date'].dt.date).

Ottieni il punteggio massimo giornaliero per ogni data, convertendo prima i valori di testo in numeri interi allo scopo di ottenere il valore massimo (rispetto al valore max lex ordinato). Converti di nuovo il risultato in una stringa.

Creare un dataframe dei punteggi massimi giornalieri, utilizzando la posizione dell'indice del datetime minimo per ciascuna data, ad es index=gb['date'].idxmin().

Questo dataframe dell'indicizzato daily_max_scorepuò ora essere unito al dataframe originale (che si unisce all'indice per impostazione predefinita), producendo il risultato desiderato.

Si noti che sia i scoreche daily_max_scoresono ancora stringhe (cioè oggetti), che è il modo in cui sono stati originariamente assegnati e quindi si deduce che siano il tipo desiderato.

df['date'] = pd.to_datetime(df['date'])
gb = df.groupby(df['date'].dt.date)
max_daily_scores = gb['score'].apply(lambda x: x.astype(int).max()).astype(str)
daily_max_score = pd.DataFrame(
    max_daily_scores.tolist(), 
    index=gb['date'].idxmin(), 
    columns=['daily_max_score']
)

>>> df.join(daily_max_score)
                 date    ID score daily_max_score
0 2019-04-19 23:00:00  ID F    50              50
1 2019-04-20 00:00:00  ID F   100             100
2 2019-04-20 01:00:00  ID F    99             NaN
3 2019-04-05 08:00:00  ID F    99              99
4 2019-07-31 23:30:00  ID B    75              75
5 2019-08-01 00:00:00  ID B    25              80
6 2019-08-01 01:00:00  ID B    25             NaN
7 2019-08-01 02:00:00  ID B    80             NaN