J'ai un bloc de données comme ci-dessous.
unit_1 unit_2 4 5 9 3
Je voudrais regrouper les données par unités, conserver le nombre minimum similaire de dernières observations en fonction du temps (l'unité 2 a 2 observations), et créez un groupe séparé pour la colonne s1. Donc, quelque chose comme ci-dessous.
unit time s1 s2 .... 1 1 2 3 1 2 4 5 1 3 9 7 2 1 5 2 2 2 3 1
Merci.
3 Réponses :
Groupby
et transmettez la liste des nième
valeurs. Supprimez les colonnes indésirables. Transposez le dataframe et ajoutez une unité de préfixe aux noms. Transposer et défaire pour combiner les colonnes
g= df.groupby('unit', group_keys=False).nth([-1,-2]).drop(columns=['time','s2']).T.add_prefix('unit_')#.unstack('s1') final = pd.DataFrame({'unit_1': g['unit_1'].values.T.ravel(), 'unit_2': g['unit_2'].values.T.ravel()}) final unit_1 unit_2 0 4 5 1 9 3
pouvez-vous changer ".apply (lambda x: x.iloc [-2:])" au lieu de ".nlargest (2)"?
Ceci est incorrect car il renvoie uniquement les plus grandes valeurs de s1 .. non basées sur le temps. L'iloc aidera cependant. cela devrait le réparer.
Votre deuxième solution fonctionne, mais la première donne juste le même résultat que df.groupby (['unit']) ['unit', 's1']. Tail (2)
Cela devrait résoudre votre problème -
def f(col): filt = df[['unit',col]].groupby('unit').tail(2) #filter last 2 filt['count'] = filt.groupby('unit').cumcount() #add a counter column for pivot #Use counter column as index and unit as column for pivot, then add prefix filt = filt.pivot(index='count',columns='unit',values=col).reset_index(drop=True).add_prefix("unit_") return filt
unit unit_1 unit_2 0 4 5 1 9 3
Utilisez cette fonction pour une exécution plus rapide.
def f(col): #First step is to get the last 2 for each group using .tail(2) dff = df[['unit','time',col]].sort_values(by=['unit','time'],axis=0).groupby(['unit']).tail(2) #Next we need the ordered rank of the time values instead of the actual values of time, #since then we can keep the time values 2,3 as 1,2 and 1,2 as 1,2. dff['time'] = dff.groupby(['unit']).rank() #Last we pivot over the time and units to get the columns that you need for correlation analysis dff = dff.pivot(index='time',columns='unit',values=col).reset_index(drop=True).add_prefix('unit_') return dff f('s1')
p>
Donc, j'ai fait cette solution:
unit_1 unit_2 0 4 5 1 9 3
Et le résultat est:
import pandas as pd import numpy as np df = pd.DataFrame({'units': [1,1,1,2,2], 's1':[2,4,9,5,3]}) new_df = df.groupby('units').tail(2) # Taking the last 2 values new_df Out: units s1 1 1 4 2 1 9 3 2 5 4 2 3 units_list = new_df.units.unique() # How many units do we have? units_columns = [] # For col names form_dict = {} # We have 2 values for each unit, so the number of elements is 2n, # where n is a number of unit corresponding the new_df. n = 0 for unit in units_list: units_columns.append('unit_{}'.format(unit)) while n != len(new_df['s1']): for col in units_columns: form_dict.update({col:new_df['s1'][n:n+2].values}) n += 2 final_df = pd.DataFrame(form_dict) final_df
Qu'entendez-vous par garder «le dernier nombre minimum similaire de dernières overvations»? Pourquoi l'unité 1, la valeur s1 de 2 est-elle écartée? Vous avez besoin de 2 valeurs maximum? Ou vous voulez les 2 dernières valeurs basées sur le temps?
Je veux les 2 dernières valeurs basées sur le temps. Désolé pour le malentendu. Ça a changé.
En outre, pouvez-vous montrer ce qui arrive à s2 dans l'exemple de la sortie? Faites-vous des lignes séparées? ou colonnes?
Je voudrais le supprimer. Je veux calculer la corrélation entre la même colonne de différents groupes. Donc, je ferais une procédure similaire pour s2 dans une boucle.