Saltar al contenido

Concatenar todas las columnas en un marco de datos de pandas

Solución:

Solución con sum, pero la salida es float, así que conviértelo a int y str es necesario:

df['new'] = df.sum(axis=1).astype(int).astype(str)

Otra solucion con apply función join, pero es el más lento:

df['new'] = df.apply(''.join, axis=1)

Dura muy rapido numpy solution – convertir a numpy array y luego ‘suma’:

df['new'] = df.values.sum(axis=1)

Tiempos:

df = pd.DataFrame({'A': ['1', '2', '3'], 'B': ['4', '5', '6'], 'C': ['7', '8', '9']})
#[30000 rows x 3 columns]
df = pd.concat([df]*10000).reset_index(drop=True)
#print (df)

cols = list('ABC')

#not_a_robot solution
In [259]: %timeit df['concat'] = pd.Series(df[cols].fillna('').values.tolist()).str.join('')
100 loops, best of 3: 17.4 ms per loop

In [260]: %timeit df['new'] = df[cols].astype(str).apply(''.join, axis=1)
1 loop, best of 3: 386 ms per loop

In [261]: %timeit df['new1'] = df[cols].values.sum(axis=1)
100 loops, best of 3: 6.5 ms per loop

In [262]: %timeit df['new2'] = df[cols].astype(str).sum(axis=1).astype(int).astype(str)
10 loops, best of 3: 68.6 ms per loop

EDITAR Si los dtypes de algunas columnas no son object (obviamente strings) emitido por DataFrame.astype:

df['new'] = df.astype(str).values.sum(axis=1)

df = pd.DataFrame({'A': ['1', '2', '3'], 'B': ['4', '5', '6'], 'C': ['7', '8', '9']})

df['concat'] = pd.Series(df.fillna('').values.tolist()).str.join('')

Nos da:

df
Out[6]: 
   A  B  C concat
0  1  4  7    147
1  2  5  8    258
2  3  6  9    369

Para seleccionar un conjunto de columnas determinado:

df['concat'] = pd.Series(df[['A', 'B']].fillna('').values.tolist()).str.join('')

df
Out[8]: 
   A  B  C concat
0  1  4  7     14
1  2  5  8     25
2  3  6  9     36

Sin embargo, he notado que el enfoque a veces puede resultar en NaNs están poblados donde no deberían, así que aquí hay otra forma:

>>> from functools import reduce
>>> df['concat'] = df[cols].apply(lambda x: reduce(lambda a, b: a + b, x), axis=1)
>>> df
   A  B  C concat
0  1  4  7    147
1  2  5  8    258
2  3  6  9    369

Aunque cabe señalar que este enfoque es mucho más lento:

$ python3 -m timeit 'import pandas as pd;from functools import reduce; df=pd.DataFrame({"a": ["this", "is", "a", "string"] * 5000, "b": ["this", "is", "a", "string"] * 5000});[df[["a", "b"]].apply(lambda x: reduce(lambda a, b: a + b, x)) for _ in range(10)]'
10 loops, best of 3: 451 msec per loop

Versus

$ python3 -m timeit 'import pandas as pd;from functools import reduce; df=pd.DataFrame({"a": ["this", "is", "a", "string"] * 5000, "b": ["this", "is", "a", "string"] * 5000});[pd.Series(df[["a", "b"]].fillna("").values.tolist()).str.join(" ") for _ in range(10)]'
10 loops, best of 3: 98.5 msec per loop

No tengo suficiente reputación para comentar, así que estoy construyendo mi respuesta a partir de la respuesta de blacksite.

Para mayor claridad, LunchBox comentó que falló para Python 3.7.0. También me falló en Python 3.6.3. Aquí está la respuesta original de blacksite:

df['concat'] = pd.Series(df.fillna('').values.tolist()).str.join('')

Aquí está mi modificación para Python 3.6.3:

df['concat'] = pd.Series(df.fillna('').values.tolist()).map(lambda x: ''.join(map(str,x)))
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *