Pandas cuenta ocurrencias únicas por mes

Tengo algunos datos mensuales que estoy tratando de resumir utilizando Pandas y necesito contar la cantidad de entradas únicas que ocurren cada mes. Aquí hay un código de ejemplo que muestra lo que estoy tratando de hacer:

import pandas as pd mnths = ['JAN','FEB','MAR','APR'] custs = ['A','B','C',] testFrame = pd.DataFrame(index=custs, columns=mnths) testFrame['JAN']['A'] = 'purchased Prod' testFrame['JAN']['B'] = 'No Data' testFrame['JAN']['C'] = 'Purchased Competitor' testFrame['FEB']['A'] = 'purchased Prod' testFrame['FEB']['B'] = 'purchased Prod' testFrame['FEB']['C'] = 'purchased Prod' testFrame['MAR']['A'] = 'No Data' testFrame['MAR']['B'] = 'No Data' testFrame['MAR']['C'] = 'Purchased Competitor' testFrame['APR']['A'] = 'Purchased Competitor' testFrame['APR']['B'] = 'purchased Prod' testFrame['APR']['C'] = 'Purchased Competitor' uniqueValues = pd.Series(testFrame.values.ravel()).unique() #CODE TO GET COUNT OF ENTRIES IN testFrame BY UNIQUE VALUE 

Salida deseada:

  JAN FEB MAR APR purchased Prod ? ? ? ? Purchased Competitor ? ? ? ? No Data ? ? ? ? 

Puedo obtener los valores únicos y crear un nuevo dataframe con los ejes / columnas correctos

Comencé aquí y aquí: Pandas: contando valores únicos en un dataframe Encuentre valores únicos en un dataframe de Pandas, independientemente de la ubicación de la fila o columna

Pero todavía no puedo obtener la salida a los formatos que necesito. No estoy seguro de cómo aplicar la syntax df.groupby o la syntax df.apply a lo que estoy trabajando.

El relleno es opcional.

 In [40]: testFrame.apply(Series.value_counts).fillna(0) Out[40]: JAN FEB MAR APR No Data 1 0 2 0 Purchased Competitor 1 0 1 2 purchased Prod 1 3 0 1 

Aquí hay un buen truco de aplicación. Crearé una función e imprimiré lo que está entrante (y quizás incluso depurando en su). Entonces es fácil ver lo que está pasando.

 In [20]: def f(x): ....: print(x) ....: return x.value_counts() ....: In [21]: testFrame.apply(f) A purchased Prod B No Data C Purchased Competitor Name: JAN, dtype: object A purchased Prod B No Data C Purchased Competitor Name: JAN, dtype: object A purchased Prod B purchased Prod C purchased Prod Name: FEB, dtype: object A No Data B No Data C Purchased Competitor Name: MAR, dtype: object A Purchased Competitor B purchased Prod C Purchased Competitor Name: APR, dtype: object Out[21]: JAN FEB MAR APR No Data 1 NaN 2 NaN Purchased Competitor 1 NaN 1 2 purchased Prod 1 3 NaN 1 [3 rows x 4 columns] 

Así que está haciendo esta operación y luego concatiéndolas juntas (con las tags correctas)

 In [22]: testFrame.iloc[0].value_counts() Out[22]: purchased Prod 2 Purchased Competitor 1 No Data 1 dtype: int64 
 li = [testFrame.ix[:,i].value_counts() for i in range(len(mnths))] frame = pd.DataFrame(li, index=mnths) frame.fillna(value=0).swapaxes(0,1) Out[42]: JAN FEB MAR APR No Data 1 0 2 0 Purchased Competitor 1 0 1 2 purchased Prod 1 3 0 1 [3 rows x 4 columns]