2

I haben eine spezifische Reihe von Datensätzen, die in der folgenden allgemeinen Form kommen:Wie reihenweise mehrere Spalten mit Strings verketten?

import pandas as pd 
import random 
df = pd.DataFrame({'n': random.sample(xrange(1000), 3), 't0':['a', 'b', 'c'], 't1':['d','e','f'], 't2':['g','h','i'], 't3':['i','j', 'k']}) 

Die Anzahl der tn Säulen (t0, t1, t2 ... tn) variiert in Abhängigkeit von der Datenmenge abhängig, ist aber immer < 30. Mein Ziel Inhalt der tn Spalten für jede Zeile zu verschmelzen, so dass ich dieses Ergebnis erzielen (beachten Sie, dass aus Gründen der Lesbarkeit muss ich die Leerzeichen zwischen den Elementen halten):

df['result'] = df.t0 +' '+df.t1+' '+df.t2+' '+ df.t3 

enter image description here

So weit so gut. Dieser Code mag einfach sein, aber er wird ungeschickt und unflexibel, sobald ich einen anderen Datensatz erhalte, wo die Anzahl der Spalten steigt. Hier kommt meine Frage:

Gibt es eine andere Syntax, um den Inhalt über mehrere Spalten hinweg zusammenzuführen? Etwas Agnostiker auf die Anzahl Spalten, ähnlich:

df['result'] = ' '.join(df.ix[:,1:]) 

Grundsätzlich mag ich das gleiche wie die OP in dem unten stehenden Link zu erreichen, aber mit Leerzeichen zwischen den Saiten: R - concatenate row-wise across specific columns of dataframe

+3

Versuchen Sie Folgendes: http://stackoverflow.com/a/32529152/5276797 – IanS

+1

Perfekt! Die von Russ vorgeschlagene Lösung ist flexibel und einfach. Danke @IanS für das Aufzeigen dieser Antwort! – EmEs

Antwort

2

ist hier eine etwas Alternative Lösung:

In [57]: df['result'] = df.filter(regex=r'^t').apply(lambda x: x.add(' ')).sum(axis=1).str.strip() 

In [58]: df 
Out[58]: 
    n t0 t1 t2 t3 result 
0 92 a d g i a d g i 
1 916 b e h j b e h j 
2 363 c f i k c f i k 
0

der Schlüssel in Spalten (Serie) für den Betrieb von Strings en Masse ist die Series.str Accessor.

Ich kann zwei .str Methoden zu tun, was Sie wollen.

str.cat()

Die erste ist str.cat. Sie müssen von einer Serie ausgehen, aber Sie können eine Liste von Serien übergeben (leider können Sie keinen Datenrahmen übergeben), um mit einem optionalen Trennzeichen zu verketten.Mit Ihrem Beispiel:

column_names = df.columns[1:] # skipping the first, numeric, column 
series_list = [df[c] for c in column_names[1:]] 
# concatenate: 
df['result'] = series_list[0].str.cat(series_list[1:], sep=' ') 

Oder in einer Zeile:

df['result'] = df[df.columns[1]].str.cat([df[c] for c in df.columns[2:]], sep=' ') 

str.join()

Die zweite ist die .str.join() Methode, die wie die Standard-Python-Methode funktioniert string.join(), aber für die Sie brauchen eine Spalte (Reihe) von Iterablen haben, zum Beispiel eine Tupelspalte, die wir erhalten, indem wir tuples zeilenweise auf einen Teildatenrahmen der Spalten anwenden, an denen Sie interessiert sind:

tuple_series = df[column_names].apply(tuple, axis=1) 
df['result'] = tuple_series.str.join(' ') 

Oder in einer Zeile:

df['result'] = df[df.columns[1:]].apply(tuple, axis=1).str.join(' ') 

BTW, versuchen Sie nicht, die oben mit list statt tuple. Ab pandas-0.20.1, wenn die Funktion, die an die Dataframe.apply()-Methode übergeben wird, eine list zurückgibt und die zurückgegebene Liste die gleichen Nummerneinträge wie die Spalten des ursprünglichen (untergeordneten) Datenrahmens hat, gibt Dataframe.apply() eine Dataframe anstelle einer Series zurück.