Convierta todo el dataframe de minúsculas a mayúsculas con Pandas

Tengo un dataframe como el que se muestra a continuación:

# Create an example dataframe about a fictional army raw_data = {'regiment': ['Nighthawks', 'Nighthawks', 'Nighthawks', 'Nighthawks'], 'company': ['1st', '1st', '2nd', '2nd'], 'deaths': ['kkk', 52, '25', 616], 'battles': [5, '42', 2, 2], 'size': ['l', 'll', 'l', 'm']} df = pd.DataFrame(raw_data, columns = ['regiment', 'company', 'deaths', 'battles', 'size']) 

introduzca la descripción de la imagen aquí

Mi objective es transformar cada una de las cadenas dentro del dataframe a mayúsculas para que se vea así:

introduzca la descripción de la imagen aquí

Aviso: todos los tipos de datos son objetos y no deben modificarse; La salida debe contener todos los objetos. Quiero evitar convertir cada columna individual una por una … Me gustaría hacerlo generalmente en todo el dataframe, posiblemente.

    Lo que intenté hasta ahora es hacer esto pero sin éxito.

     df.str.upper() 

    astype () emitirá cada serie al objeto dtype (cadena) y luego invocará el método str () en la serie convertida para obtener la cadena literalmente y llamar a la función upper () en ella. Tenga en cuenta que después de esto, el tipo de todas las columnas cambia a objeto.

     In [17]: df Out[17]: regiment company deaths battles size 0 Nighthawks 1st kkk 5 l 1 Nighthawks 1st 52 42 ll 2 Nighthawks 2nd 25 2 l 3 Nighthawks 2nd 616 2 m In [18]: df.apply(lambda x: x.astype(str).str.upper()) Out[18]: regiment company deaths battles size 0 NIGHTHAWKS 1ST KKK 5 L 1 NIGHTHAWKS 1ST 52 42 LL 2 NIGHTHAWKS 2ND 25 2 L 3 NIGHTHAWKS 2ND 616 2 M 

    Más tarde, puede convertir la columna de ‘batallas’ a numérica nuevamente, usando to_numeric () :

     In [42]: df2 = df.apply(lambda x: x.astype(str).str.upper()) In [43]: df2['battles'] = pd.to_numeric(df2['battles']) In [44]: df2 Out[44]: regiment company deaths battles size 0 NIGHTHAWKS 1ST KKK 5 L 1 NIGHTHAWKS 1ST 52 42 LL 2 NIGHTHAWKS 2ND 25 2 L 3 NIGHTHAWKS 2ND 616 2 M In [45]: df2.dtypes Out[45]: regiment object company object deaths object battles int64 size object dtype: object 

    Esto se puede resolver mediante la siguiente operación de aplicación de mapa:

     df = df.applymap(lambda s:s.lower() if type(s) == str else s) 

    Como str solo funciona para series, puede aplicarla a cada columna individualmente y luego concatenar:

     In [6]: pd.concat([df[col].astype(str).str.upper() for col in df.columns], axis=1) Out[6]: regiment company deaths battles size 0 NIGHTHAWKS 1ST KKK 5 L 1 NIGHTHAWKS 1ST 52 42 LL 2 NIGHTHAWKS 2ND 25 2 L 3 NIGHTHAWKS 2ND 616 2 M 

    Edición: comparación de rendimiento

     In [10]: %timeit df.apply(lambda x: x.astype(str).str.upper()) 100 loops, best of 3: 3.32 ms per loop In [11]: %timeit pd.concat([df[col].astype(str).str.upper() for col in df.columns], axis=1) 100 loops, best of 3: 3.32 ms per loop 

    Ambas respuestas funcionan de igual manera en un pequeño dataframe.

     In [15]: df = pd.concat(10000 * [df]) In [16]: %timeit pd.concat([df[col].astype(str).str.upper() for col in df.columns], axis=1) 10 loops, best of 3: 104 ms per loop In [17]: %timeit df.apply(lambda x: x.astype(str).str.upper()) 10 loops, best of 3: 130 ms per loop 

    En un gran dataframe mi respuesta es ligeramente más rápida.

    Si desea conservar el uso de dtype es isinstance(obj,type)

     df.apply(lambda x: x.str.upper().str.strip() if isinstance(x, object) else x) 

    prueba esto

     df2 = df2.apply(lambda x: x.str.upper() if x.dtype == "object" else x)