J'ai une trame de données avec des rangées de 200K et j'essaie d'ajouter des colonnes en fonction d'autres lignes avec certaines conditions. J'ai essayé de l'atteindre mais prenez beaucoup de temps (2 heures).
Voici mon code: P>
A_id B_id C_date D E D_mean E_mean 0 1 10 2019-02-22 10 7 NaN NaN 1 2 20 2019-02-28 12 10 NaN NaN 2 1 10 2019-07-03 21 14 10.0 7.0 3 2 20 2019-03-14 81 31 12.0 10.0 4 1 10 2019-12-21 20 61 15.5 10.5 5 2 20 2019-11-10 1 9 46.5 20.5
3 Réponses :
Nous pouvons utiliser une combinaison de fonctions pour y parvenir, la plus notable que le pd.dataframe.rolling code> pour calculer la moyenne mobile.
def custom_agg(group):
cols = ['D', 'E']
for col in cols:
name = '{}_mean'.format(col)
group[name] = group[col].shift() \
.rolling(len(group[col]), min_periods=2) \
.mean() \
.fillna(group[col].iloc[0])
group[name].iloc[0] = pd.np.nan
return group
dataset.groupby(['A_id', 'B_id'], as_index=False).apply(custom_agg)
A_id B_id C_date D E D_mean E_mean
0 1 10 2019-02-22 10 7 NaN NaN
1 2 20 2019-02-28 12 10 NaN NaN
2 1 10 2019-07-03 21 14 10.0 7.0
3 2 20 2019-03-14 81 31 12.0 10.0
4 1 10 2019-12-21 20 61 15.5 10.5
5 2 20 2019-11-10 1 9 46.5 20.5
Cela a fonctionné pour moi. Votre solution est 7 fois plus rapide que la mienne. Merci
J'ai soupçonné que votre création de sous-ensemble dans la boucle était chère et que mes tests ont révélé que votre algorithme fonctionnait à environ 11 000 indices par minute. J'ai proposé un algorithme alternatif qui pré-trie les données de sorte que le calcul du sous-ensemble devienne trivial et s'exécutant sur un ensemble de données de données de 200K de données aléatoires prend moins de 5 minutes.
dataset.sort_values(by=['A_id', 'B_id', 'C_date'], inplace=True)
dataset.reset_index(drop=True, inplace=True)
last_A = None
last_B = None
first_index = -1
for index in dataset.index:
A_id = dataset.loc[index, 'A_id']
B_id = dataset.loc[index, 'B_id']
C_date = dataset.loc[index, 'C_date']
if (last_A != A_id) | (last_B != B_id):
first_index = index
last_A = A_id
last_B = B_id
subset = dataset[first_index:index]
dataset.at[index, 'D_mean'] = subset['D'].mean()
dataset.at[index, 'E_mean'] = subset['E'].mean()
itération sur chaque rangée dans un fichier de données n'est pas un optimal i> ou idéal i> solution
Je n'étais pas au courant de la fonction applicable. Je retrouverai ma solution pour utiliser cela.
L'utilisation simplement appliquer code> est la même que celle itérante sur chaque ligne, l'objectif ultime des pandas est d'utiliser leurs fonctions intégrées vectorisées.
Voici une seule façon de faire en utilisant .apply code>: