Solución:
Hay un nuevo módulo llamado patsy que resuelve este problema. El inicio rápido vinculado a continuación resuelve exactamente el problema descrito anteriormente en un par de líneas de código.
-
http://patsy.readthedocs.org/en/latest/overview.html
-
http://patsy.readthedocs.org/en/latest/quickstart.html
Aquí hay un ejemplo de uso:
import pandas
import patsy
dataFrame = pandas.io.parsers.read_csv("salary2.txt")
#salary2.txt is a re-formatted data set from the textbook
#Introductory Econometrics: A Modern Approach
#by Jeffrey Wooldridge
y,X = patsy.dmatrices("sl ~ 1+sx+rk+yr+dg+yd",dataFrame)
#X.design_info provides the meta data behind the X columns
print X.design_info
genera:
> DesignInfo(['Intercept',
> 'sx[T.male]',
> 'rk[T.associate]',
> 'rk[T.full]',
> 'dg[T.masters]',
> 'yr',
> 'yd'],
> term_slices=OrderedDict([(Term([]), slice(0, 1, None)), (Term([EvalFactor('sx')]), slice(1, 2, None)),
> (Term([EvalFactor('rk')]), slice(2, 4, None)),
> (Term([EvalFactor('dg')]), slice(4, 5, None)),
> (Term([EvalFactor('yr')]), slice(5, 6, None)),
> (Term([EvalFactor('yd')]), slice(6, 7, None))]),
> builder=<patsy.build.DesignMatrixBuilder at 0x10f169510>)
import pandas
import numpy as np
num_rows = 7;
df2 = pandas.DataFrame(
{
'a' : ['one', 'one', 'two', 'three', 'two', 'one', 'six'],
'b' : ['x', 'y', 'y', 'x', 'y', 'x', 'x'],
'c' : np.random.randn(num_rows)
}
)
a_attribute_list = ['one', 'two', 'three', 'six']; #Or use list(set(df2['a'].values)), but that doesn't guarantee ordering.
b_attribute_list = ['x','y']
a_membership = [ np.reshape(np.array(df2['a'].values == elem).astype(np.float64), (num_rows,1)) for elem in a_attribute_list ]
b_membership = [ np.reshape((df2['b'].values == elem).astype(np.float64), (num_rows,1)) for elem in b_attribute_list ]
c_column = np.reshape(df2['c'].values, (num_rows,1))
design_matrix_a = np.hstack(tuple(a_membership))
design_matrix_b = np.hstack(tuple(b_membership))
design_matrix = np.hstack(( design_matrix_a, design_matrix_b, c_column ))
# Print out the design matrix to see that it's what you want.
for row in design_matrix:
print row
Obtengo esta salida:
[ 1. 0. 0. 0. 1. 0. 0.36444463]
[ 1. 0. 0. 0. 0. 1. -0.63610264]
[ 0. 1. 0. 0. 0. 1. 1.27876991]
[ 0. 0. 1. 0. 1. 0. 0.69048607]
[ 0. 1. 0. 0. 0. 1. 0.34243241]
[ 1. 0. 0. 0. 1. 0. -1.17370649]
[ 0. 0. 0. 1. 1. 0. -0.52271636]
Entonces, la primera columna es un indicador de las ubicaciones de DataFrame que fueron ‘una’, la segunda columna es un indicador de las ubicaciones de DataFrame que fueron ‘dos’, y así sucesivamente. Las columnas 4 y 5 son indicadores de las ubicaciones de DataFrame que eran ‘x’ e ‘y’, respectivamente, y la columna final son solo los datos aleatorios.
Pandas 0.13.1 del 3 de febrero de 2014 tiene un método:
>>> pd.Series(['one', 'one', 'two', 'three', 'two', 'one', 'six']).str.get_dummies()
one six three two
0 1 0 0 0
1 1 0 0 0
2 0 0 0 1
3 0 0 1 0
4 0 0 0 1
5 1 0 0 0
6 0 1 0 0