Diese Frage wurde bereits beantwortet, aber ich glaube, es wäre gut, einige nützliche Methoden, die zuvor nicht erörtert wurden, in den Mix aufzunehmen und alle bisher vorgeschlagenen Methoden hinsichtlich der Leistung zu vergleichen.
Hier sind einige nützliche Lösungen für dieses Problem in aufsteigender Reihenfolge der Leistung.
Dies ist ein einfacher str.format
Ansatz.
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
Sie können hier auch die F-String-Formatierung verwenden:
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
Konvertieren Sie die Spalten so chararrays
, dass sie verkettet werden , und fügen Sie sie dann zusammen.
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
Ich kann nicht übertreiben, wie unterschätzt das Listenverständnis bei Pandas ist.
df['baz'] = [str(x) + ' is ' + y for x, y in zip(df['bar'], df['foo'])]
Alternativ mit str.join
concat (wird auch besser skaliert):
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
Listenverständnisse zeichnen sich durch die Manipulation von Zeichenfolgen aus, da Zeichenfolgenoperationen von Natur aus schwer zu vektorisieren sind und die meisten "vektorisierten" Pandas-Funktionen im Grunde genommen Wrapper um Schleifen sind. Ich habe ausführlich über dieses Thema in For-Schleifen mit Pandas geschrieben - Wann sollte es mich interessieren? . Wenn Sie sich keine Gedanken über die Indexausrichtung machen müssen, verwenden Sie im Allgemeinen ein Listenverständnis, wenn Sie mit Zeichenfolgen- und Regex-Operationen arbeiten.
Die obige Liste enthält standardmäßig keine NaNs. Sie können jedoch jederzeit eine Funktion schreiben, die einen Versuch umschließt, es sei denn, Sie müssen damit umgehen.
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
Leistungsmessungen
Grafik erstellt mit Perfplot . Hier ist die vollständige Codeliste .
Funktionen
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'])])