Obtener la primera letra de una cadena de la columna

Estoy peleando con pandas y por ahora estoy perdiendo. Tengo tabla de origen similar a esto:

import pandas as pd a=pd.Series([123,22,32,453,45,453,56]) b=pd.Series([234,4353,355,453,345,453,56]) df=pd.concat([a, b], axis=1) df.columns=['First', 'Second'] 

Me gustaría agregar una nueva columna a este dataframe con el primer dígito de los valores en la columna ‘Primero’: a) cambiar el número a la cadena de la columna ‘Primero’ b) extraer el primer carácter de la cadena recién creada c) Los resultados de b guardar como nuevo columna en el dataframe

No sé cómo aplicar esto al objeto de dataframe pandas. Estaría agradecido por ayudarme con eso.

dtype el dtype de dtype de la columna a la str y puedes realizar la secuencia de llamada de segmentación vectorizada:

 In [29]: df['new_col'] = df['First'].astype(str).str[0] df Out[29]: First Second new_col 0 123 234 1 1 22 4353 2 2 32 355 3 3 453 453 4 4 45 345 4 5 453 453 4 6 56 56 5 

Si lo necesita, puede volver a lanzar el dtype llamando a astype(int) en la columna.

.str.get

Este es el método más simple para especificar cadenas.

 # Setup df = pd.DataFrame({'A': ['xyz', 'abc', 'foobar'], 'B': [123, 456, 789]}) df AB 0 xyz 123 1 abc 456 2 foobar 789 df.dtypes A object B int64 dtype: object 

Para columnas de tipo cadena (leer: object ), use

 df['C'] = df['A'].str[0] # Similar to, df['C'] = df['A'].str.get(0) 

.str controla NaNs devolviendo NaN como la salida.

Para las columnas no numéricas, se requiere una conversión de .astype antemano, como se muestra en la respuesta de @Ed Chum.

 # Note that this won't work well if the data has NaNs. # It'll return lowercase "n" df['D'] = df['B'].astype(str).str[0] 

 df ABCD 0 xyz 123 x 1 1 abc 456 a 4 2 foobar 789 f 7 

Comprensión de listas e indexación

Hay evidencia suficiente para sugerir que una comprensión de lista simple funcionará bien aquí y probablemente sea más rápida.

 # For string columns df['C'] = [x[0] for x in df['A']] # For numeric columns df['D'] = [str(x)[0] for x in df['B']] 

 df ABCD 0 xyz 123 x 1 1 abc 456 a 4 2 foobar 789 f 7 

Si sus datos tienen NaN, entonces deberá manejar esto de manera adecuada con un if / else en la lista de comprensión,

 df2 = pd.DataFrame({'A': ['xyz', np.nan, 'foobar'], 'B': [123, 456, np.nan]}) df2 AB 0 xyz 123.0 1 NaN 456.0 2 foobar NaN # For string columns df2['C'] = [x[0] if isinstance(x, str) else np.nan for x in df2['A']] # For numeric columns df2['D'] = [str(x)[0] if pd.notna(x) else np.nan for x in df2['B']] ABCD 0 xyz 123.0 x 1 1 NaN 456.0 NaN 4 2 foobar NaN f NaN 

Vamos a hacer algunas pruebas de tiempo en algunos datos más grandes.

 df_ = df.copy() df = pd.concat([df_] * 5000, ignore_index=True) %timeit df.assign(C=df['A'].str[0]) %timeit df.assign(D=df['B'].astype(str).str[0]) %timeit df.assign(C=[x[0] for x in df['A']]) %timeit df.assign(D=[str(x)[0] for x in df['B']]) 

 12 ms ± 253 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 27.1 ms ± 1.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 3.77 ms ± 110 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 7.84 ms ± 145 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 

Las comprensiones en lista son 4 veces más rápidas.