2012-09-20 46 views
29

Tengo una columna en un DataFrame de pandas que me gustaría dividir en un solo espacio. La división es bastante simple con DataFrame.str.split(' '), pero no puedo hacer una nueva columna desde la última entrada. Cuando yo .str.split() la columna obtengo una lista de matrices y no sé cómo manipular esto para obtener una nueva columna para mi DataFrame.Obtener la última "columna" después de la operación .str.split() en la columna en pandas DataFrame

Aquí hay un ejemplo. Cada entrada en la columna contiene 'precio de datos de símbolo' y me gustaría dividir el precio (y eventualmente eliminar la "p" ... o "c" en la mitad de los casos).

import pandas as pd 
temp = pd.DataFrame({'ticker' : ['spx 5/25/2001 p500', 'spx 5/25/2001 p600', 'spx 5/25/2001 p700']}) 
temp2 = temp.ticker.str.split(' ') 

que produce

0 ['spx', '5/25/2001', 'p500'] 
1 ['spx', '5/25/2001', 'p600'] 
2 ['spx', '5/25/2001', 'p700'] 

Pero temp2[0] simplemente da gama de una entrada de la lista y temp2[:][-1] falla. ¿Cómo puedo convertir la última entrada en cada arreglo a una nueva columna? ¡Gracias!

Respuesta

28

se puede utilizar el método tolist como intermediario:

In [99]: import pandas as pd 

In [100]: d1 = pd.DataFrame({'ticker' : ['spx 5/25/2001 p500', 'spx 5/25/2001 p600', 'spx 5/25/2001 p700']}) 

In [101]: d1.ticker.str.split().tolist() 
Out[101]: 
[['spx', '5/25/2001', 'p500'], 
['spx', '5/25/2001', 'p600'], 
['spx', '5/25/2001', 'p700']] 

desde donde se podía hacer una nueva trama de datos:

In [102]: d2 = pd.DataFrame(d1.ticker.str.split().tolist(), 
    .....:     columns="symbol date price".split()) 

In [103]: d2 
Out[103]: 
    symbol  date price 
0 spx 5/25/2001 p500 
1 spx 5/25/2001 p600 
2 spx 5/25/2001 p700 

Por si fuera poco, se podría fijar el precio:

In [104]: d2["price"] = d2["price"].str.replace("p","").astype(float) 

In [105]: d2 
Out[105]: 
    symbol  date price 
0 spx 5/25/2001 500 
1 spx 5/25/2001 600 
2 spx 5/25/2001 700 

PD: pero si realmente sólo quieren la última columna, apply sería suficiente:

In [113]: temp2.apply(lambda x: x[2]) 
Out[113]: 
0 p500 
1 p600 
2 p700 
Name: ticker 
+0

Esto me ayudó a agregar un archivo de registro en pandas que era demasiado aterrador y complicado incluso para tocar antes (una sola columna de datos con mucha información por fila). – trench

+0

Todos estos enfoques tienen un rendimiento desastroso en comparación con la respuesta de Wes McKinney. –

+1

@JohnZwinck: wow, un voto a favor relacionado con el rendimiento en una respuesta de hace cinco años sobre la funcionalidad que solo se había introducido aproximadamente [dos meses antes] (https://github.com/pandas-dev/pandas/issues/1656)? Eso es ... riguroso, ¡te daré eso! – DSM

49

hacer esto:

In [43]: temp2.str[-1] 
Out[43]: 
0 p500 
1 p600 
2 p700 
Name: ticker 
+3

¡Me encanta la solución limpia! – ericmjl

+4

del autor de "Pandas" :) – kmonsoor

+3

Me encanta esta solución, pero ¿cómo funciona? Es decir, ¿qué está sucediendo "entre bastidores" que permite que "str", seguido por corchetes, seleccione un elemento específico de la lista? –

0

Usando pandas 0.20.3:

In [10]: import pandas as pd 
    ...: temp = pd.DataFrame({'ticker' : ['spx 5/25/2001 p500', 'spx 5/25/2001 p600', 'spx 5/25/2001 p700']}) 
    ...: 

In [11]: temp2 = temp.ticker.str.split(' ', expand=True) # the expand=True return a DataFrame 

In [12]: temp2 
Out[12]: 
    0   1  2 
0 spx 5/25/2001 p500 
1 spx 5/25/2001 p600 
2 spx 5/25/2001 p700 

In [13]: temp3 = temp.join(temp2[2]) 

In [14]: temp3 
Out[14]: 
       ticker  2 
0 spx 5/25/2001 p500 p500 
1 spx 5/25/2001 p600 p600 
2 spx 5/25/2001 p700 p700 
Cuestiones relacionadas