Cette question a déjà reçu une réponse, mais je pense qu'il serait bon d'ajouter quelques méthodes utiles qui n'ont pas encore été abordées, et de comparer toutes les méthodes proposées jusqu'à présent en termes de performances.
Voici quelques solutions utiles à ce problème, par ordre croissant de performance.
Il s'agit d'un simple str.format
-L'approche est basée sur l'expérience.
df['baz'] = df.agg('{0[bar]} is {0[foo]}'.format, axis=1)
df
foo bar baz
0 a 1 1 is a
1 b 2 2 is b
2 c 3 3 is c
Vous pouvez également utiliser le formatage f-string ici :
df['baz'] = df.agg(lambda x: f"{x['bar']} is {x['foo']}", axis=1)
df
foo bar baz
0 a 1 1 is a
1 b 2 2 is b
2 c 3 3 is c
char.array
-Concaténation à base de
Convertir les colonnes à concaténer comme chararrays
puis ajoutez-les ensemble.
a = np.char.array(df['bar'].values)
b = np.char.array(df['foo'].values)
df['baz'] = (a + b' is ' + b).astype(str)
df
foo bar baz
0 a 1 1 is a
1 b 2 2 is b
2 c 3 3 is c
Je ne saurais trop insister sur le fait que les compréhensions de listes sont sous-estimées dans les pandas.
df['baz'] = [str(x) + ' is ' + y for x, y in zip(df['bar'], df['foo'])]
On peut aussi utiliser str.join
pour concaténer (ce qui permettra également une meilleure mise à l'échelle) :
df['baz'] = [
' '.join([str(x), 'is', y]) for x, y in zip(df['bar'], df['foo'])]
df
foo bar baz
0 a 1 1 is a
1 b 2 2 is b
2 c 3 3 is c
Les compréhensions de listes excellent dans la manipulation des chaînes de caractères, car les opérations sur les chaînes de caractères sont par nature difficiles à vectoriser, et la plupart des fonctions "vectorisées" de pandas sont essentiellement des enveloppes autour des boucles. J'ai beaucoup écrit sur ce sujet dans Boucles For avec les pandas - Quand faut-il s'en préoccuper ? . En général, si vous n'avez pas à vous soucier de l'alignement de l'index, utilisez une compréhension de liste pour les opérations sur les chaînes de caractères et les regex.
La liste comp ci-dessus par défaut ne gère pas les NaNs. Cependant, vous pouvez toujours écrire une fonction enveloppant un try-except si vous avez besoin de les gérer.
def try_concat(x, y):
try:
return str(x) + ' is ' + y
except (ValueError, TypeError):
return np.nan
df['baz'] = [try_concat(x, y) for x, y in zip(df['bar'], df['foo'])]
perfplot
Mesures de la performance
Graphique généré à l'aide de perfplot . Voici le liste complète des codes .
Fonctions
def brenbarn(df):
return df.assign(baz=df.bar.map(str) + " is " + df.foo)
def danielvelkov(df):
return df.assign(baz=df.apply(
lambda x:'%s is %s' % (x['bar'],x['foo']),axis=1))
def chrimuelle(df):
return df.assign(
baz=df['bar'].astype(str).str.cat(df['foo'].values, sep=' is '))
def vladimiryashin(df):
return df.assign(baz=df.astype(str).apply(lambda x: ' is '.join(x), axis=1))
def erickfis(df):
return df.assign(
baz=df.apply(lambda x: f"{x['bar']} is {x['foo']}", axis=1))
def cs1_format(df):
return df.assign(baz=df.agg('{0[bar]} is {0[foo]}'.format, axis=1))
def cs1_fstrings(df):
return df.assign(baz=df.agg(lambda x: f"{x['bar']} is {x['foo']}", axis=1))
def cs2(df):
a = np.char.array(df['bar'].values)
b = np.char.array(df['foo'].values)
return df.assign(baz=(a + b' is ' + b).astype(str))
def cs3(df):
return df.assign(
baz=[str(x) + ' is ' + y for x, y in zip(df['bar'], df['foo'])])