2016-04-25 12 views
1

Ich habe Daten, die ich als Datenframe aus einer CSV mit Pandas (in Python) einlesen. Die CSV sieht im Grunde wie folgt aus:Pivot Gruppen von Zeilendaten in Spalten mit Pandas

image img1.jpg 
date  Thursday, May 5 
link  bit.ly/asdf 
subject 'Unique subject line 1' 
image img2.jpg 
date  Tuesday, May 17 
link  bit.ly/zxcv 
subject 'Unique subject line 2' 
image img3.jpg 
date  Monday, May 9 
link  bit.ly/sdfg 
subject 'Unique subject line 3' 

Ich mag es in einen Datenrahmen erhalten, wobei jede eindeutige Gruppierung in einer einzigen Reihe ist, mit den Attributen, die derzeit als Zeilendaten in Spalte 1 als Spalte aufgeführt sind Namen. So etwas wie folgen aus:

image  date     link   subject 
img1.jpg Thursday, May 5  bit.ly/asdf 'Unique subject line 1' 
img2.jpg Tuesday, May 17  bit.ly/zxcv 'Unique subject line 2' 
img3.jpg Monday, May 9  bit.ly/sdfg 'Unique subject line 3' 

Ich habe versucht pandas.pivot_table mit und auch nur einen leeren Datenrahmen mit den Säulen zu schaffen ich will, aber mit beiden Methoden, ich bin entweder mit Indizierung oder Aggregieren Probleme habe. Ich denke, das liegt daran, dass ich nicht nach einem Attribut gruppiere, und ich versuche nicht, irgendwelche numerischen Daten zu aggregieren.

Es scheint, als sollte es einfach genug sein, um die Daten auf diese Weise umzuformen, aber ich bin mir nicht sicher, wie ich die gewünschten Gruppierungen definieren soll. Gibt es eine Möglichkeit, dies mit pivot_table zu tun, oder wäre es am besten, es auf eine andere Weise zu tun?

Antwort

1

Das Problem besteht darin, dass es während der Formatierung der Daten keine eindeutige Möglichkeit gibt, die Bilder während eines Drehpunkts zu gruppieren. Jedes Datum kann während eines Pivot-Vorgangs mit img1.jpg gruppiert werden, da keine zusätzlichen Daten darüber vorliegen, welches Datum zu welchem ​​Bild gehören soll.

Um dies zu beheben, müssen wir nur eine zusätzliche Spalte mit den Gruppierungsinformationen hinzufügen. Gemessen an Ihrer Ausgabe erfolgt die Gruppierung im Wesentlichen in Zeilenreihenfolge; die ersten 4 Reihen gehören zusammen, die nächsten 4 Reihen gehören zusammen usw. Um Wiederholungen wie diese aufzuzählen, ist numpy.repeat nützlich, Sie müssen nur die Anzahl der Bilder und Attribute kennen. Einige grundlegende mathematische uns erlaubt, die Anzahl der Bilder und die Anzahl der Attribute im Allgemeinen zu erhalten:

# Add an grouping column. 
nbr_images = (df['col1'] == 'image').sum() 
nbr_attributes = len(df)/nbr_images 
df['image_group'] = np.repeat(range(nbr_images), nbr_attributes) 

Jetzt ist es einfach zu schwenken:

# Pivot the DataFrame. 
pivoted_df = df.pivot(columns='col1', index='image_group', values='col2') 

# Clear the index and column name. 
pivoted_df.index.name = None 
pivoted_df.columns.name = None 

Die resultierende Ausgabe:

   date  image   link    subject 
0 Thursday, May 5 img1.jpg bit.ly/asdf Unique subject line 1 
1 Tuesday, May 17 img2.jpg bit.ly/zxcv Unique subject line 2 
2 Monday, May 9 img3.jpg bit.ly/sdfg Unique subject line 3 
+0

ausgezeichnet, danke! Für alle anderen mit ähnlich strukturierten Daten musste ich df.pivot verwenden (Spalten = 0, Werte = 1, Index = 'Bildgruppe') ODER Namen zu den Spalten hinzufügen, die zum Pivot für die Argumente columns und values ​​übergeben wurden. – nicolekanderson

0

Ich denke, Sie können cumsum für die Erstellung image_group und dann pivot mit rename_axis (neu in pandas0.18.0):

df['image_group'] = (df.col1 == 'image').cumsum() - 1 
print df.pivot(columns='col1', index='image_group', values='col2') 
     .rename_axis(None) 
     .rename_axis(None, axis=1) 

       date  image   link     subject 
0 Thursday, May 5 img1.jpg bit.ly/asdf 'Unique subject line 1' 
1 Tuesday, May 17 img2.jpg bit.ly/zxcv 'Unique subject line 2' 
2 Monday, May 9 img3.jpg bit.ly/sdfg 'Uniquesubject line 3' 

Alternativ können Sie eine Zeile verwenden:

print pd.pivot(columns=df['col1'], 
       index=(df.col1 == 'image').cumsum() - 1, 
       values=df['col2']) 
     .rename_axis(None) 
     .rename_axis(None, axis=1) 

       date  image   link     subject 
0 Thursday, May 5 img1.jpg bit.ly/asdf 'Unique subject line 1' 
1 Tuesday, May 17 img2.jpg bit.ly/zxcv 'Unique subject line 2' 
2 Monday, May 9 img3.jpg bit.ly/sdfg 'Uniquesubject line 3' 

EDIT: Wenn Spalten der ursprünglichen Datenrahmen sind 0 und 1 Verwendung iloc zur Auswahl:

print pd.pivot(columns=df.iloc[:,0], 
       index=(df.iloc[:,0] == 'image').cumsum() - 1, 
       values=df.iloc[:,1]) 
     .rename_axis(None) 
     .rename_axis(None, axis=1) 

       date  image   link     subject 
0 Thursday, May 5 img1.jpg bit.ly/asdf 'Unique subject line 1' 
1 Tuesday, May 17 img2.jpg bit.ly/zxcv 'Unique subject line 2' 
2 Monday, May 9 img3.jpg bit.ly/sdfg 'Uniquesubject line 3'