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

178
Visualizações
No está claro por qué groupby con un solo grupo produce fila DataFrame

Aquí hay dos operaciones groupby en un pandas.DataFrame :

 import pandas d = pandas.DataFrame({"a": [1, 2, 3, 4, 5, 6], "b": [1, 2, 4, 3, -1, 5]}) grp1 = pandas.Series([1, 1, 1, 1, 1, 1]) ans1 = d.groupby(grp1).apply(lambda x: xa * xbiloc[0]) grp2 = pandas.Series([1, 1, 1, 2, 2, 2]) ans2 = d.groupby(grp2).apply(lambda x: xa * xbiloc[0]) print(ans1.reset_index(drop=True)) # a 0 1 2 3 4 5 # 0 1 2 3 4 5 6 print(ans2.reset_index(drop=True)) # 0 1 # 1 2 # 2 3 # 3 12 # 4 15 # 5 18 # Name: a, dtype: int64

Quiero la salida en el formato de ans2 . Si la Serie de agrupación tiene más de un grupo (como en grp2 ), entonces no hay problema con el formato de salida. Sin embargo, cuando la agrupación Series tiene solo un grupo (como en grp1 ), la salida es un DataFrame con una sola fila. ¿Por qué es esto?

¿Cómo puedo asegurarme de que la salida siempre será como ans2 independientemente del número de grupos en la serie de agrupación? ¿Hay un enfoque más rápido/mejor que

  1. Comprobando si la salida es un DataFrame y coaccionando en una Serie
  2. Comprobando si la serie de agrupación tiene solo un grupo y evitando groupby si ese es el caso
over 4 years ago · Santiago Trujillo
4 Respostas
Responde à pergunta

0

Creo que lo más fácil es evitar .apply() que, de hecho, hace cosas raras cuando se recombina. Probablemente esto se deba a que la semántica de esta función es muy vaga. Puedes devolver cualquier cosa y los pandas harán todo lo posible para adivinar lo que quisiste decir.

Si desea resultados consistentes con funciones que se aplican a todo el sub-marco de datos, es mejor que ejecute la función usted mismo:

 >>> pd.concat({n: (lambda x: xa * xbiloc[0])(g) for n, g in d.groupby(grp1)}) 1 0 1 1 2 2 3 3 4 4 5 5 6 Name: a, dtype: int64 >>> pd.concat({n: (lambda x: xa * xbiloc[0])(g) for n, g in d.groupby(grp2)}) 1 0 1 1 2 2 3 2 3 12 4 15 5 18 Name: a, dtype: int64

Ahora, lo que recomendaría es usar una función con una forma de retorno bien definida. Aquí .transform() podría ser útil:

 >>> d.groupby(grp1)['b'].transform('first') 0 1 1 1 2 1 3 1 4 1 5 1 Name: b, dtype: int64 >>> d.groupby(grp2)['b'].transform('first') 0 1 1 1 2 1 3 3 4 3 5 3 Name: b, dtype: int64

Aquí hay un ejemplo de cómo podría usar para el mismo cálculo:

 >>> ans1 = d.copy() >>> ans1['a'] *= d.groupby(grp1)['b'].transform('first') >>> ans1 ab 0 1 1 1 2 2 2 3 4 3 4 3 4 5 -1 5 6 5 >>> ans2 = d.copy() >>> ans2['a'] *= d.groupby(grp2)['b'].transform('first') >>> ans2 ab 0 1 1 1 2 2 2 3 4 3 12 3 4 15 -1 5 18 5
over 4 years ago · Santiago Trujillo Relatório

0

Una solución simple es devolver un DataFrame desde apply :

 import pandas d = pandas.DataFrame({"a": [1, 2, 3, 4, 5, 6], "b": [1, 2, 4, 3, -1, 5]}) grp1 = pandas.Series([1, 1, 1, 1, 1, 1]) ans1 = d.groupby(grp1).apply(lambda x: x[['a']] * xbiloc[0]) grp2 = pandas.Series([1, 1, 1, 2, 2, 2]) ans2 = d.groupby(grp2).apply(lambda x: x[['a']] * xbiloc[0]) print(ans1.reset_index(drop=True)) # a # 0 1 # 1 2 # 2 3 # 3 4 # 4 5 # 5 6 print(ans2.reset_index(drop=True)) # a # 0 1 # 1 2 # 2 3 # 3 12 # 4 15 # 5 18

Para entender por qué, la documentación de la función de apply es útil. Cuando la función dada para apply devuelve una Series , se convierten en una fila y el resultado final es un DataFrame de datos con una fila por grupo. Entonces, el comportamiento de grp1 es el esperado.

Esto plantea la pregunta de por qué el segundo caso que usa grp2 devuelve una Series . Creo que se debe a que los dos grupos devuelven Series con diferentes valores de índice. Por lo tanto, los resultados de los dos grupos se agregan en una sola fila con indexación multinivel (como se ve a continuación).

 d = pandas.DataFrame({"a": [1, 2, 3, 4, 5, 6], "b": [1, 2, 4, 3, -1, 5]}) grp2 = pandas.Series([1, 1, 1, 2, 2, 2]) def func(x): z= xa * xbiloc[0] print(z.index) return z ans2 = d.groupby(grp2).apply(func) # Int64Index([0, 1, 2], dtype='int64') # Int64Index([3, 4, 5], dtype='int64') print(ans2) # 1 0 1 # 1 2 # 2 3 # 2 3 12 # 4 15 # 5 18 # Name: a, dtype: int64
over 4 years ago · Santiago Trujillo Relatório

0

Esto sucede porque, como solo tiene un grupo con grp1 , el intermedio se convierte primero como Serie y luego como DataFrame con el grupo como índice, en lugar de agregar un nivel de MultiIndex como con grp2 .

Para evitar esto, puede dividir sus datos como un marco de datos en su lambda y subestablecer la columna en Serie solo después de la agregación. Esto asegura que el resultado intermedio permanecerá en la dimensión correcta:

 >>> ans1 = d.groupby(grp1).apply(lambda x: x[['a']] * xbiloc[0])['a'] >>> ans1 0 1 1 2 2 3 3 4 4 5 5 6 Name: a, dtype: int64 >>> ans2 = d.groupby(grp2).apply(lambda x: x[['a']] * xbiloc[0])['a'] >>> ans2 0 1 1 2 2 3 3 12 4 15 5 18 Name: a, dtype: int64

Dicho esto, lo más fácil es usar transform :

 >>> d.groupby(grp1)['a'].transform(lambda x: x*d.loc[x.index[0], 'b']) 0 1 1 2 2 3 3 4 4 5 5 6 Name: a, dtype: int64 >>> d.groupby(grp2)['a'].transform(lambda x: x*d.loc[x.index[0], 'b']) 0 1 1 2 2 3 3 12 4 15 5 18 Name: a, dtype: int64
over 4 years ago · Santiago Trujillo Relatório

0

Otra forma, además de usar transform , para asegurarse de tener el mismo formato de salida es usar squeeze :

 >>> ans1.squeeze().reset_index(drop=True) 0 1 1 2 2 3 3 4 4 5 5 6 Name: 1, dtype: int64 >>> ans2.squeeze().reset_index(drop=True) 0 1 1 2 2 3 3 12 4 15 5 18 Name: a, dtype: int64

Puede usar squeeze=True en groupby pero generará un FutureWarning :

FutureWarning: el parámetro de squeeze está en desuso y se eliminará en una versión futura.

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