2 votes

Vérifier la valeur de la colonne d'index suivante et la longueur consécutive de la même valeur dans le cadre de données Pandas.

Je veux vérifier si la colonne d'index suivante a la même valeur que la colonne d'index précédente et aussi obtenir la longueur consécutive de la même valeur.

Par exemple, il y a un cadre de données ci-dessous, et je veux obtenir la longueur des valeurs consécutives de 0.

    1 2 3 4 5 6 
a   1 0 0 1 1 1
b   0 0 0 1 0 0
c   1 0 1 0 1 0
d   1 1 1 1 1 1

Résultat :

  • la ligne a a deux valeurs 0 consécutives, la longueur est donc de 2
  • la ligne b a trois valeurs 0 consécutives, la longueur est donc de 3
  • la ligne c n'a pas de valeur 0 consécutive donc la longueur est de 1
  • la ligne d n'a pas de valeur de 0 donc la longueur est de 0

De plus, si le premier indice commence par 0, ne comptez pas jusqu'à ce que la valeur 1 apparaisse et commencez à compter la longueur avec le 0 suivant.

  • En appliquant cette condition, le résultat de la ligne b devrait être 2.

Il y a plus de 1000000 lignes dans les données réelles, donc la boucle for prendra trop de temps, donc je veux savoir s'il y a un moyen de le faire dans pandas ou d'une autre manière.

1voto

jezrael Points 290608

L'idée est de créer df1 pour un nombre consécutif 0 et obtenir maximum valeur pour new1 . Pour le second, c'est plus compliqué - obtenir les indices de la première valeur maximale (voici les valeurs maximales 1 pour obtenir les indices de la première 1 ) et créer un masque pour l'ensemble 0 par masque, donc le prochain sum omettre premier seulement 0 groupes.

Aussi si seulement 0 les rangs renvoient une sortie erronée, il est donc nécessaire de changer la condition avec de multiples pour les ~a.all(axis=1).values[:, None] pour l'empêcher :

a = df == 0
b = a.cumsum(axis=1)
df1 = (b-b.where(~a, axis=1).ffill(axis=1).fillna(0).astype(int))

cols = np.arange(len(df.columns))
n = np.argmax(df.values, axis=1)[:, None]

mask = (cols > n) * ~a.all(axis=1).values[:, None]

df['new1'] = df1.max(axis=1)
df['new2'] = df1.where(mask, 0).max(axis=1)
print (df)
   1  2  3  4  5  6  new1  new2
a  1  0  0  1  1  1     2     2
b  0  0  0  1  0  0     3     2
c  1  0  1  0  1  0     1     1
d  1  1  1  1  1  1     0     0

Détails :

print (df1)
   1  2  3  4  5  6
a  0  1  2  0  0  0
b  1  2  3  0  1  2
c  0  1  0  1  0  1
d  0  0  0  0  0  0

print (df1.where(mask, 0))
   1  2  3  4  5  6
a  0  1  2  0  0  0
b  0  0  0  0  1  2
c  0  1  0  1  0  1
d  0  0  0  0  0  0

Vérifier la solution avec seulement 0 rang :

print (df)
   1  2  3  4  5  6
a  1  0  0  1  1  1
b  0  0  0  0  0  0 <- only 0 row
c  1  0  1  0  1  0
d  1  1  1  1  1  1

a = df == 0
b = a.cumsum(axis=1)
df1 = (b-b.where(~a, axis=1).ffill(axis=1).fillna(0).astype(int))

cols = np.arange(len(df.columns))
n = np.argmax(df.values, axis=1)[:, None]

print (df1)
   1  2  3  4  5  6
a  0  1  2  0  0  0
b  1  2  3  4  5  6 <- count all 0
c  0  1  0  1  0  1
d  0  0  0  0  0  0

print (df1.where(mask, 0))
   1  2  3  4  5  6
a  0  1  2  0  0  0
b  0  0  0  0  0  0 <- correct not count this row
c  0  1  0  1  0  1
d  0  0  0  0  0  0

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X