¿Cómo puedo calcular el número de valores consecutivos en una columna dentro de un grupo en un contexto de Pandas? -- python campo con pandas campo con dataframe camp Relacionados El problema

How can I calculate number of consecutive values in a column within a group in a pandas dataframe?


0
vote

problema

Español

Tengo un conteo de datos con todas las peleas de un luchador, el número de lucha (es decir, si es su primer, segundo, etc.), y si ganaron o no la pelea. Me gustaría calcular la cantidad de victorias consecutivas que un luchador había llegado antes de su lucha actual (es decir, no incluirse si ganaron la lucha actual). Actualmente estoy trabajando con Python 3.7 en Spyder.

Supongamos que tenemos el siguiente contexto de datos, donde Win = 1 si el luchador ganó la lucha:

  df = pd.DataFrame({'fighter' : ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C'],                    'fight_number' :  ['1', '2', '3', '4', '1', '2', '3', '1', '2'],                   'win' : [0, 0, 1, 1, 1, 1, 0, 1, 1]})   
    fighter  fight_number  win 0       A             1     0 1       A             2     0 2       A             3     1 3       A             4     1 4       B             1     1 5       B             2     1 6       B             3     0 7       C             1     1 8       C             2     1   

Sé que para calcular las rayas de ganar en todas las filas, puedo implementar la solución propuesta aquí < / a> con:

  grouper = (df.win != df.win.shift()).cumsum() df['streak'] = df.groupby(grouper).cumsum()   

que produce:

    fighter fight_number  win  streak 0       A            1    0       0 1       A            2    0       0 2       A            3    1       1 3       A            4    1       2 4       B            1    1       3 5       B            2    1       4 6       B            3    0       0 7       C            1    1       1 8       C            2    1       2   

Pero lo que necesito es aplicar este enfoque a los subgrupos del frasco de datos (es decir, a cada luchador) y no incluir el resultado de la lucha actual en el recuento de la racha. Entonces, básicamente estoy tratando de tener la racha de victorias actuales del luchador cuando entran en la lucha.

La salida objetivo en este ejemplo, por lo tanto, sería:

    fighter fight_number  win  streak 0       A            1    0       0 1       A            2    0       0 2       A            3    1       0 3       A            4    1       1 4       B            1    1       0 5       B            2    1       1 6       B            3    0       2 7       C            1    1       0 8       C            2    1       1   

Aprecio cualquier consejo que pueda obtener sobre esto, ya que soy bastante nuevo en Python.

Original en ingles

I have a dataframe with all of a fighter's fights, the fight number (i.e. if it is their first, second, etc.), and whether or not they won the fight. I would like to calculate the number of consecutive wins a fighter had gotten before their current fight (i.e. not including if they won the current fight). I am currently working with Python 3.7 in Spyder.

Suppose we have the following dataframe, where win = 1 if the fighter won the fight:

df = pd.DataFrame({'fighter' : ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C'],                    'fight_number' :  ['1', '2', '3', '4', '1', '2', '3', '1', '2'],                   'win' : [0, 0, 1, 1, 1, 1, 0, 1, 1]}) 
  fighter  fight_number  win 0       A             1     0 1       A             2     0 2       A             3     1 3       A             4     1 4       B             1     1 5       B             2     1 6       B             3     0 7       C             1     1 8       C             2     1 

I know that to calculate win streaks across all rows, I can implement the solution proposed here with:

grouper = (df.win != df.win.shift()).cumsum() df['streak'] = df.groupby(grouper).cumsum() 

which produces:

  fighter fight_number  win  streak 0       A            1    0       0 1       A            2    0       0 2       A            3    1       1 3       A            4    1       2 4       B            1    1       3 5       B            2    1       4 6       B            3    0       0 7       C            1    1       1 8       C            2    1       2 

But what I need is to apply this approach to subgroups of the dataframe (i.e. to each fighter) and to not include the outcome of the current fight in the count of the streak. So, I am basically trying to have the current win streak of the fighter when they enter the fight.

The target output in this example would therefore be:

  fighter fight_number  win  streak 0       A            1    0       0 1       A            2    0       0 2       A            3    1       0 3       A            4    1       1 4       B            1    1       0 5       B            2    1       1 6       B            3    0       2 7       C            1    1       0 8       C            2    1       1 

I appreciate any advice I can get on this, as I am pretty new to Python.

        
   
   

Lista de respuestas

0
 
vote
vote
La mejor respuesta
 

Una solución que acumulé fue inspirada en una respuesta anterior publicada (pero eliminada) por jezrael :

  grouper = (df.win != df.win.shift()).cumsum() df['streak'] = df.groupby(['fighter', grouper]).cumsum() df['streak'] = df.groupby('fighter')['streak'].shift(1).fillna(0)   

que produce la salida de destino:

    fighter fight_number  win  streak 0       A            1    0     0.0 1       A            2    0     0.0 2       A            3    1     0.0 3       A            4    1     1.0 4       B            1    1     0.0 5       B            2    1     1.0 6       B            3    0     2.0 7       C            1    1     0.0 8       C            2    1     1.0   

y también parece funcionar en otros ejemplos de prueba:

  df2 = pd.DataFrame({'fighter' : ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C'],                    'fight number' :  ["1", "2", "3", "4", "5", "6", "1", "2", "3", "1", "2"],                   'win' : [1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1]})   grouper = (df2.win != df2.win.shift()).cumsum() df2['streak'] = df2.groupby(['fighter', grouper]).cumsum() df2['streak'] = df2.groupby('fighter')['streak'].shift(1).fillna(0)     fighter fight number  win  streak 0        A            1    1     0.0 1        A            2    1     1.0 2        A            3    0     2.0 3        A            4    1     0.0 4        A            5    0     1.0 5        A            6    1     0.0 6        B            1    1     0.0 7        B            2    1     1.0 8        B            3    0     2.0 9        C            1    1     0.0 10       C            2    1     1.0    
 

One solution I came up with was inspired by an earlier answer posted (but deleted) by jezrael:

grouper = (df.win != df.win.shift()).cumsum() df['streak'] = df.groupby(['fighter', grouper]).cumsum() df['streak'] = df.groupby('fighter')['streak'].shift(1).fillna(0) 

which produces the target output:

  fighter fight_number  win  streak 0       A            1    0     0.0 1       A            2    0     0.0 2       A            3    1     0.0 3       A            4    1     1.0 4       B            1    1     0.0 5       B            2    1     1.0 6       B            3    0     2.0 7       C            1    1     0.0 8       C            2    1     1.0 

and it also seems to work on other test examples:

df2 = pd.DataFrame({'fighter' : ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C'],                    'fight number' :  ["1", "2", "3", "4", "5", "6", "1", "2", "3", "1", "2"],                   'win' : [1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1]})   grouper = (df2.win != df2.win.shift()).cumsum() df2['streak'] = df2.groupby(['fighter', grouper]).cumsum() df2['streak'] = df2.groupby('fighter')['streak'].shift(1).fillna(0)     fighter fight number  win  streak 0        A            1    1     0.0 1        A            2    1     1.0 2        A            3    0     2.0 3        A            4    1     0.0 4        A            5    0     1.0 5        A            6    1     0.0 6        B            1    1     0.0 7        B            2    1     1.0 8        B            3    0     2.0 9        C            1    1     0.0 10       C            2    1     1.0  
 
 

Relacionados problema

0  Fusionar con el minuto más cercano usando Pandas  ( Merge with the nearest minute using pandas ) 
Simplemente quiero fusionar dos cuadros de datos dentro de ± 1 min. AQUÍ NAME_DF con el conjunto de datos de muestra: Name Date A 2/19/2019 17:1...

2  Cambiar filas en pandas  ( Change rows in pandas ) 
Tengo una matriz en marco de datos de Pandas print dfMatrix 0 1 2 3 4 0 10000 10 8 11 10 1 10 100000 ...

12  Deshacerse de las filas con atributos duplicados en r  ( Get rid of rows with duplicate attributes in r ) 
Tengo un gran contorno de datos con columnas tales como: ID, time, OS, IP Cada fila de ese flujo de datos corresponde a una entrada. Dentro de ese prot...

96  Cómo explotar una lista dentro de una celda de datos de datos en filas separadas  ( How to explode a list inside a dataframe cell into separate rows ) 
Estoy buscando convertir una célula PANDAS que contiene una lista en filas para cada uno de esos valores. Entonces, toma esto: Si me gustaría desempaca...

4  Usando RBIND () para combinar múltiples marcos de datos en uno de los datos más grandes.Frame dentro de LAPLY ()  ( Using rbind to combine multiple data frames into one larger data frame within ) 
Estoy usando R-Studio 0.99.491 y R versión 3.2.3 (2015-12-10). Soy un relative Newbie a R, y apreciaría algo de ayuda. Estoy haciendo un proyecto donde estoy ...

1  Pandas DataFrame al diccionario con tuplas como clave y valores  ( Pandas dataframe to dictionary with tuples as key and values ) 
Necesito ayuda para hacer lo siguiente: Tengo un archivo CSV como lo siguiente, cargado en un Frame 'DF'. Hay varias regiones, diferentes valores para la me...

1  Filtrando cada columna de un marco de datos un PUT NA para valores inigualables  ( Filtering each column of a data frame an put na for unmatched values ) 
Tengo una tabla de la siguiente manera: [,1] [,2] [,3] [,4] [,5] [1,] a A 0.06 0.31 -1.5 [2,] b B -0.75 0.2 0.02 [3,] ...

1  R - Quiero que el nombre de la línea de datos sea determinada por un argumento de línea de comandos  ( R i want data frame name to be determined by a command line argument ) 
Quiero que se determine un nombre de marco de datos por un argumento de línea de comandos. Lo siguiente debería dejarlo claro lo que estaba tratando de hacer ...

1  Cambio de entradas en un fotograma de datos dependiendo de si están entre dos valores o por debajo de un valor  ( Changing entries in a dataframe depending on whether they are between two values ) 
Tengo un conteo de datos con la distancia en una columna y puntuaciones en otra columna, por ejemplo. Distance Scores 1000. 1 1500. 1 etc. Teng...

1  ¿Puedes usar Pandas Groupby para agrupar filas, determinado sumando un valor de columna?  ( Can you use pandas groupby to group rows determined by summing a column value ) 
Me gustaría agrupar filas en un contexto de datos por valores de una columna. El ejemplo dado a continuación sería si estuviera agrupando los valores de 'Numb...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos