2016-09-08 5 views
1

extrahieren habe ich eine csv, die wie unten aussieht:kann nicht eindeutigen Wörter aus einer CSV-

Description 
0 ['boy'] 
1 ['boy', 'jumped', 'roof'] 
2 ['paris'] 
3 ['paris', 'beautiful', 'new', 'york'] 
4 ['lets', 'go', 'party'] 
5 ['refused', 'come', 'party'] 

Ich einzigartige Worte aus diesen Daten herausfinden müssen. So würde Ausgabe sein:

Unique Words 
0 boy 
1 jumped 
2 roof 
3 paris 
4 beautiful 
5 new 
6 york 

als so weiter. Ich versuche dies mit Pandas und Python zu tun und nicht in der Lage dies zu erreichen. Mein Code ist:

df = pd.read_csv('output.csv') 
list(set(df.Description)) 
g = list(df['Description'].unique()) 
print(g) 

Dies wirft falsche Ausgabe, es wirft nur den ursprünglichen CSV-Datenframe.

+0

Ich würde vermuten, dass die Spalte Ihres Dataframes entweder Listen enthält, deren Elemente diese Wörter sind oder dass sie diese Listen im Zeichenfolgenformat enthält, also eine lange Zeichenfolge mit allen Wörtern pro Zeile. So oder so würde es die "eindeutige" Operation auf diesen Listen/vollständigen Strings statt der einzelnen Strings tun. – Khris

Antwort

3

Sie können zuerst string Spalte zu list konvertieren, ich verwende ast.literal_eval. Dann machen Sie flache Liste von Listen Listenverständnis, verwenden set und letzte neue DataFrame von Konstruktor erstellen:

import ast 

print (type(df.ix[0, 'Description'])) 
<class 'str'> 

df.Description = df.Description.apply(ast.literal_eval) 

print (type(df.ix[0, 'Description'])) 
<class 'list'> 

#http://stackoverflow.com/q/952914/2901002 
unique_data = list(set([item for sublist in df.Description.tolist() for item in sublist])) 
print (unique_data) 
['refused', 'jumped', 'go', 'roof', 'come', 'beautiful', 
'paris', 'york', 'lets', 'new', 'boy', 'party'] 

print (pd.DataFrame({'Unique Words': unique_data})) 
    Unique Words 
0  refused 
1  jumped 
2   go 
3   roof 
4   come 
5  beautiful 
6   paris 
7   york 
8   lets 
9   new 
10   boy 
11  party 

Eine andere Lösung ohne ast:

df.Description = df.Description.str.strip('[]').str.split(',') 
print (df) 
           Description 
0         ['boy'] 
1    ['boy', 'jumped', 'roof'] 
2         ['paris'] 
3 ['paris', 'beautiful', 'new', 'york'] 
4     ['lets', 'go', 'party'] 
5   ['refused', 'come', 'party'] 

unique_data = list(set([item.strip().strip("'") for sublist in df.Description.tolist() for item in sublist])) 
print (unique_data) 
['refused', 'jumped', 'go', 'roof', 'come', 'beautiful', 
'paris', 'york', 'lets', 'new', 'boy', 'party'] 

print (pd.DataFrame({'Unique Words': unique_data})) 
    Unique Words 
0  refused 
1  jumped 
2   go 
3   roof 
4   come 
5  beautiful 
6   paris 
7   york 
8   lets 
9   new 
10   boy 
11  party 
+0

Ihre Lösung ohne 'Ast' ist die schnellste. – Khris

+0

Vielen Dank für das Testen. – jezrael

1

Dieser Ansatz funktioniert:

import pandas as pd 
import ast 

test = {'Description':["['boy']","['boy', 'jumped', 'roof']","['paris']",\ 
"['paris', 'beautiful', 'new', 'york']","['lets', 'go', 'party']",\ 
"['refused', 'come', 'party']"]} 

tt = pd.DataFrame(test) 

listOfWords = [] 
for i,row in tt.iterrows(): 
    listOfWords.extend(ast.literal_eval(tt.ix[i,'Description'])) 
uniqueWords = pd.DataFrame(listOfWords,columns=['Unique Words']).drop_duplicates() 

Wenn Sie es sortiert haben möchten:

uniqueWords = uniqueWords.sort_values('Unique Words') 

Sie durchlaufen alle Zeilen, konvertieren Ihre Strings in Listen und sammeln alle diese Listen in einer langen Liste mit extend. Dann erstellen Sie einfach einen neuen Datenrahmen aus dieser Liste und legen Sie die Duplikate ab.

EDIT: Dank Jezrael für die Korrektur meiner Lösung, ich borgte die ast.literal_eval Ansatz von seiner Lösung.

Ich habe versucht, unsere Lösungen mit dem %timeit Befehl zu vergleichen, aber ValueError: malformed string auf ast.literal_eval in beiden Lösungen.

EDIT2: Jezrael Lösung ist doppelt so schnell für die kleinen Daten Beispiel wir hier haben.

EDIT3: Ich kann nicht mit einem großen Datenbeispiel testen (multiplizieren Sie das gegebene mit einer Nummer), weil timeitmalformed string Fehler aus Gründen wirft, die für mich unklar sind.

EDIT4: Hat es irgendwie funktioniert. Für einen größeren Datensatz (6000 Zeilen) ist die Lösung von Jezrael über 8-mal schneller. Raten sogar mit iterrows iterieren ist eher langsam im Vergleich zu Liste Verständnis. Auch habe ich jezraels zweite Lösung ohne ast getestet. Es ist mehr als doppelt so schnell wie seine erste Lösung.

+1

Nur gibt es Problem OP lesen 'csv', so' type' von Werten von 'input df' sind' strings', die wie 'lists' aussieht. – jezrael

+0

Sie haben Recht, ich werde es in Kürze korrigieren und Lösungen vergleichen. – Khris

+0

Ihr ist schneller. :) – Khris

Verwandte Themen