Grupo de pandas por cuenta única como nueva columna.

Quiero agregar una nueva columna de col en el dataframe de mis pandas que se calculará como:

 select count(distinct ITEM) as col from base_data where STOCK > 0 group by DEPT, CLAS, DATE; 

Por lo que estoy haciendo

 assort_size = base_data[(base_data['STOCK'] > 0)]\ .groupby(['DEPT','CLAS','DATE'])['ITEM']\ .transform('nunique') 

Básicamente, para cada departamento, clase y combinación de fechas, quiero obtener el número de artículos que están en stock. Entonces quiero obtener el resultado de esta combinación con el dataframe principal, pero el resultado está saliendo como pandas.core.series.Series por lo que no puedo pandas.core.series.Series append (axis=1) hacia atrás (el recuento de filas difiere, por ejemplo, 1.6 M Vs 1.4 M). Además, no tengo columnas DEPT, CLAS, DATE para unir. ¿Qué puedo hacer aquí para obtener el dataframe con agrupar por columnas?

¿Hay alguna forma mejor de crear una nueva columna directamente en el dataframe pandas principal ( base_data ) que creando un nuevo objeto como estoy creando assort_size ?

Puede usar la boolean indexing primero, luego groupby con nunique y la última join :

 base_data = pd.DataFrame({"DEPT": ["a", "a", "b", "b"], "CLAS":['d','d','d','d'], "STOCK": [-1, 1, 2,2], "DATE":pd.to_datetime(['2001-10-10','2001-10-10', '2001-10-10','2001-10-10']), "ITEM":[1,2,3,4]}) print (base_data) CLAS DATE DEPT ITEM STOCK 0 d 2001-10-10 a 1 -1 1 d 2001-10-10 a 2 1 2 d 2001-10-10 b 3 2 3 d 2001-10-10 b 4 2 assort_size = base_data[(base_data['STOCK'] > 0)]\ .groupby(['DEPT','CLAS','DATE'])['ITEM'].nunique().rename('n_item') print (assort_size) DEPT CLAS DATE ad 2001-10-10 1 bd 2001-10-10 2 Name: n_item, dtype: int64 print (base_data.join(assort_size, on=['DEPT','CLAS','DATE'])) CLAS DATE DEPT ITEM STOCK n_item 0 d 2001-10-10 a 1 -1 1 1 d 2001-10-10 a 2 1 1 2 d 2001-10-10 b 3 2 2 3 d 2001-10-10 b 4 2 2 

Puede usar apply lugar de transform para cálculos complejos y mover el filtro dentro de la función aplicar, usar assign para hacer una nueva columna para cada grupo, esto creará un dataframe con la columna recién calculada, no se necesita una asignación posterior:

 (base_data.groupby(['DEPT','CLAS','DATE'], group_keys=False) .apply(lambda g: g.assign(n_item = g.ITEM[g.STOCK > 0].nunique()))) 

Un ejemplo : (encuentre el número de valores únicos en la columna C donde B> 0 agrupado por la columna A)

 df = pd.DataFrame({"A": ["a", "a", "b", "b"], "B": [-1, 1, 2,2],"C":[1,2,3,4]}) df.groupby('A', group_keys=False).apply(lambda g: g.assign(n_item = gC[gB > 0].nunique())) # ABC n_item #0 a -1 1 1 #1 a 1 2 1 #2 b 2 3 2 #3 b 2 4 2