Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

517
Visualizações
Restar dos valores de una misma columna en un dataframe de Pandas

A partir de este DataFrame con nombre df

SampleTargetCtCt MeanC41B2M20.64239920.680149C41B2M20.71790120.680149C42ULK129.09788329.110802C42ULK129.12372229.110802C43TBP22.12641221,4221565C43TBP20.71790121,4221565

La columna Ct Mean es la media de los dos valores de la columna Ct de la misma Sample y Target (esto te lo da por defecto el .xlsx que importo al pandas).

Mi intención es comprobar si la diferencia entre los dos valores de la columna Ct para la misma muestra y target no es mayor a +-1 dos a dos. Por ejemplo, para C41 (B2M) la diferencia entre 20.642399 y 20.717901 es menor a 1 con lo cual debería devolver el valor de Ct tal cual. En cambio, para C43 (TBP) la diferencia entre 22.126412 y 20.717901 es mayor 1 y sustituir los dos valores de Ct para C43 por "Undetermined". El resultado que debería darme sería este:

SampleTargetCtCt MeanC41B2M20.64239920.680149C41B2M20.71790120.680149C42ULK129.09788329.110802C42ULK129.12372229.110802C43TBPUndeterminedUndeterminedC43TBPUndeterminedUndetermined

He intentado de varias formas realizar una resta entre dos elementos de una misma columna de un dataframe pero no he sido capaz. La primera era aplicar un bucle para esa columna que hiciese la diferencia entre los dos valores haciendo un salto para que luego haga los dos siguientes:

def loop(i):
    for i in range(0,96,2):
        if i-(i+1)>1 or i-(i+1)<(-1):
                i=="Undetermined"
        else:
            return i
prueba = df["Ct"].apply(loop)
prueba

Imprime:

0     0
1     0
2     0
3     0
4     0
     ..
91    0
92    0
93    0
94    0
95    0
Name: Ct, Length: 96, dtype: int64

NOTA* Mi dataframe tiene 96 filas. Solo he puesto un head con las 6 primeras para el ejemplo. Al imprimir me da todo 0. He estado buscando y vi que existe el método .diff que permite restar el valor de un elemento menos el valor del elemento anterior, pero no sé como aplicarlo. Otra manera que pensé es utilizar:

df["Ct"].sub(df[0,len(df),2], axis=0)

Obviamente da error y tampoco está bien la sintaxis.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Solución

def myfunc(g):
  if any(g.Ct.diff().abs()>1):
    g["Ct Mean"] = "Undetermined"
  return g

df = df.groupby(["Sample", "Target"]).apply(myfunc)

Demo

Si df inicialmente contiene:

  Sample Target         Ct     Ct Mean
0    C41    B2M  20.642399   20.680149
1    C41    B2M  20.717901   20.680149
2    C42   ULK1  29.097883   29.110802
3    C42   ULK1  29.123722   29.110802
4    C43    TBP  22.126412  21,4221565
5    C43    TBP  20.717901  21,4221565

el resultado del código anterior produce:

  Sample Target         Ct       Ct Mean
0    C41    B2M  20.642399     20.680149
1    C41    B2M  20.717901     20.680149
2    C42   ULK1  29.097883     29.110802
3    C42   ULK1  29.123722     29.110802
4    C43    TBP  22.126412  Undetermined
5    C43    TBP  20.717901  Undetermined

Cómo funciona

Como ves todo se resuelve en una línea:

df.groupby(["Sample", "Target"]).apply(myfunc)

Lo que hace esto es agrupar el dataframe por "Sample" y "Target" de modo que reúne en varios "sub-dataframes" las filas que tengan el mismo valor en "Sample" y "Target". A cada uno de los "sub-dataframes" resultantes (que llamaremos en adelante "grupos") se les aplica la función myfunc.

Esta función recibe por tanto en su parámetro g un grupo, que es en realidad un dataframe pero "filtrado" de modo que tiene solo un par de elementos con el mismo Sample y Target, al menos en este caso son solo un par de elementos. De forma más general reciben un dataframe con un número arbitrario de filas, con las mismas columnas que el df original, y con el mismo valor de "Sample" y "Target" en todas las filas.

Lo que hace la función es determinar si en ese grupo hay que cambiar el valor de la columna "Ct Mean" para ponerle "Undetermined" o hay que dejarlo como estaba. Después retorna el grupo en cuestión, para que .apply() lo vaya concatenando de nuevo con los restantes grupos para crear el dataframe con el resultado.

La clave para determinar si hay que poner o no "Undetermined" es la línea siguiente:

  if any(g.Ct.diff().abs()>1):

g.Ct es la columna Ct del grupo recibido. Al aplicarle .diff() se resta en esa columna a cada elemento el anterior. El primero no tiene anterior por lo que el resultado sale NaN, pero en los siguientes el resultado será la diferencia. Se tiene así una columna de diferencias. A esa columna se le aplica .abs() para quedarse con el valor absoluto de modo que el signo no influya. Se tiene por tanto una columna de números (el primero de ellos NaN).

Se compara la columna con >1 lo que nos da una nueva columna pero esta vez de booleanos. Para cada elemento de la diferencia que sea mayor de 1, habrá un True (y el resto serán False). El primero que es NaN dará False siempre. En tu caso sólo habrá un elemento más (porque sólo hay dos filas en cada grupo), pero de forma general podríamos tener una columna con muchos booleanos.

Esa columna se le pasa a any() que devuelve True si hay al menos un True entre los elementos. Sólo si todos son False devolverá False.

El resultado es que si entre los valores retornados por .diff() hay alguno mayor de 1, el if se ejecutará y entonces hará:

g["Ct Mean"] = "Undetermined"

que asigna ese valor a la columna completa, es decir, a todas las filas de ese grupo. Si el if no se cumple, g no se toca.

Finalmente la función retorna g (haya sido modificado o no).

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda