¿Cómo convertir una columna de cadena a numérica?

Tengo este dataframe pandas de una consulta:

| name | event | ---------------------------- | name_1 | event_1 | | name_1 | event_2 | | name_2 | event_1 | 

Necesito convertir el evento de columna en numérico, o algo así:

 | name | event_1 | event_2 | ------------------------------- | name_1 | 1 | 0 | | name_1 | 0 | 1 | | name_2 | 1 | 0 | 

En el software rapidminer, puedo hacer esto con un operador “nominal a numérico”, por lo que asumo que en Python Convert el tipo de columna debería ser efectivo, pero puedo equivocarme.

En la final, la idea es hacer una sum en el valor de las columnas con el mismo nombre y tener como resultado una tabla que debería tener este aspecto:

 | name | event_1 | event_2 | ------------------------------- | name_1 | 1 | 1 | | name_2 | 1 | 0 | 

Hay una función que devuelve lo que se espera?

importante: no puedo hacer un recuento simple de los eventos porque no los conozco y los eventos son diferentes para los usuarios

EDIT: bueno, gracias chicos, puedo ver que hay varias formas de hacer esto, ¿pueden decir cuál de estas es la forma más pythonica?

Algunas formas de hacerlo.

1)

 In [366]: pd.crosstab(df.name, df.event) Out[366]: event event_1 event_2 name name_1 1 1 name_2 1 0 

2)

 In [367]: df.groupby(['name', 'event']).size().unstack(fill_value=0) Out[367]: event event_1 event_2 name name_1 1 1 name_2 1 0 

3)

 In [368]: df.pivot_table(index='name', columns='event', aggfunc=len, fill_value=0) Out[368]: event event_1 event_2 name name_1 1 1 name_2 1 0 

4)

 In [369]: df.assign(v=1).pivot(index='name', columns='event', values='v').fillna(0) Out[369]: event event_1 event_2 name name_1 1.0 1.0 name_2 1.0 0.0 

Opción 1
pir1 y pir1_5

 df.set_index('name').event.str.get_dummies() event_1 event_2 name name_1 1 0 name_1 0 1 name_2 1 0 

Entonces podrías sumr todo el índice.

 df.set_index('name').event.str.get_dummies().sum(level=0) event_1 event_2 name name_1 1 1 name_2 1 0 

opcion 2
pir2
O podrías puntear el producto

 pd.get_dummies(df.name).T.dot(pd.get_dummies(df.event)) event_1 event_2 name_1 1 1 name_2 1 0 

Opcion 3
pir3
Modo avanzado

 i, r = pd.factorize(df.name.values) j, c = pd.factorize(df.event.values) n, m = r.size, c.size b = np.bincount(i * m + j, minlength=n * m).reshape(n, m) pd.DataFrame(b, r, c) event_1 event_2 name_1 1 1 name_2 1 0 

Sincronización

 res.plot(loglog=True) 

introduzca la descripción de la imagen aquí

 res.div(res.min(1), 0) pir1 pir2 pir3 john1 john2 john3 10 9.948396 3.399913 1.0 20.478368 4.460466 10.642113 30 9.350524 2.681178 1.0 16.589248 3.847666 9.168907 100 11.414536 3.079463 1.0 18.076040 4.277752 9.949305 300 15.769594 2.940529 1.0 16.745889 3.945470 9.069265 1000 26.869451 2.617564 1.0 12.789570 3.236390 7.279205 3000 42.229542 2.099541 1.0 8.716600 2.429847 4.785814 10000 52.571678 1.716088 1.0 4.597598 1.691989 2.800455 30000 58.644764 1.469827 1.0 2.818744 1.535012 1.929452 

Funciones

 pir1 = lambda df: df.set_index('name').event.str.get_dummies().sum(level=0) pir1_5 = lambda df: pd.get_dummies(df.set_index('name').event).sum(level=0) pir2 = lambda df: pd.get_dummies(df.name).T.dot(pd.get_dummies(df.event)) def pir3(df): i, r = pd.factorize(df.name.values) j, c = pd.factorize(df.event.values) n, m = r.size, c.size b = np.bincount(i * m + j, minlength=n * m).reshape(n, m) return pd.DataFrame(b, r, c) john1 = lambda df: pd.crosstab(df.name, df.event) john2 = lambda df: df.groupby(['name', 'event']).size().unstack(fill_value=0) john3 = lambda df: df.pivot_table(index='name', columns='event', aggfunc='size', fill_value=0) 

Prueba

 res = pd.DataFrame( index=[10, 30, 100, 300, 1000, 3000, 10000, 30000], columns='pir1 pir2 pir3 john1 john2 john3'.split(), dtype=float ) for i in res.index: d = pd.concat([df] * i, ignore_index=True) for j in res.columns: stmt = '{}(d)'.format(j) setp = 'from __main__ import d, {}'.format(j) res.at[i, j] = timeit(stmt, setp, number=100) 

Usted está preguntando por las formas de Pythonic, creo que en Python de esta manera es utilizar una técnica llamada encoding en caliente. Esta técnica está bien implementada en bibliotecas como Sklearn y después de una encoding en caliente tendrá que agrupar su dataframe por la primera columna y aplicar la función de sum.

Aquí hay un código:

 import pandas as pd #the useful libraries import numpy as np from sklearn.preprocessing import LabelBinarizer #form sklmearn dataset = pd.DataFrame([['name_1', 'event_1' ], ['name_1', 'event_2'], ['name_2', 'event_1']], columns=['name', 'event'], index=[1, 2, 3]) data = dataset['event'] #just reproduce your dataframe enc = LabelBinarizer(neg_label=0) dataset['event_2'] = enc.fit_transform(data) event_two = dataset['event_2'] dataset['event_1'] = (~event_two.astype(np.bool)).astype(np.int64) #this is a tip to reproduce the event_1 columns dataset = dataset.groupby('name').sum() dataset.reset_index(inplace=True) 

y la salida es:

introduzca la descripción de la imagen aquí