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 string
s) 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 NaN
s 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)))