2016-03-30 15 views
0

Ich habe einen großen Datensatz ~ 1 GB mit ~ 14 Millionen Zeilen. Ich möchte die Ländernamen aufräumen; das heißt, ersetzen Sie zum Beispiel durch CANADA.Python: Was ist eine effiziente Möglichkeit, Zeichenfolgen in Pandas zu ersetzen

Ich habe versucht:

mttt_pings.replace(['^CA$', '^US$', '^UNITED STATES$', '^MX$', '^TR$', 'GB', 
        '^ENGLAND$', '^AU$', '^FR$', '^KOREA, REPUB OF$', 
        '^CONGO, DEM REP.$', '^SYRIA$', '^DOMINICAN REP.$', 
        '^RUSSIA$', '^TAIWAN$', '^UAE$', '^LIBYA$'], 
        ['CANADA', 'UNITED STATES OF AMERICA', 
        'UNITED STATES OF AMERICA', 'MEXICO', 'TURKEY', 
        'UNITED KINGDOM', 'UNITED KINGDOM', 'AUSTRALIA', 'FRANCE', 
        'KOREA, REPUBLIC OF', 'CONGO', 'SYRIA ARAB REPUBLIC', 
        'DOMINICAN REPUBLIC', 'RUSSIA FEDERATION', 
        'TAIWAN, PROVINCE OF CHINA', 'UNITED ARAB EMIRATES', 
        'LIBYAN ARAB JAMAHIRIYA'], 
regex = True, inplace = True) 

Dies ist nur eine Teilmenge nicht einmal die volle Ersatzliste ist. Dies lief ~ 30 Minuten bevor ich den Prozess beendete.

Ich versuchte dann Schreiben einzelner replaces, aber das war immer noch zu langsam.

  • Gibt es eine bessere (effizientere) Möglichkeit, Pandas auf einer großen Anzahl von Zeilen zu ersetzen?
  • Würde eine Funktion von if-Anweisungen klüger sein und dann df.apply(function) verwenden?
  • Oder fehlt mir gerade etwas?

Ein Probensatz würde wie folgt aussehen:

import time 
import pandas as pd 
t0 = time.time() 

df = pd.DataFrame({'ser_no': [1, 1, 1, 2, 2, 2, 2, 3, 3, 3], 
        'CTRY_NM': ['a', 'a', 'b', 'e', 'e', 'a', 'b', 'b', 'b', 'd']}) 

df.replace({'^a$': 'America'}, regex = True, inplace = True) 
df.replace({'^b$': 'Bahamas'}, regex = True, inplace = True) 
df.replace({'^c$': 'Congo'}, regex = True, inplace = True) 
df.replace({'^e$': 'Europe'}, regex = True, inplace = True) 
df.replace({'^a$': 'Dominican Republic'}, regex = True, inplace = True) 
tf = time.time() 
total = tf - t0 

Offensichtlich dieser Satz zu klein ist, um in vollem Umfang die Zeit Probleme zu replizieren.

Für diesen Fall ergeben vier Läufe: tf = 0.00300002, tf = 00299978, tf = 0.00200009 und tf = 0.00300002.

import time 
import pandas as pd 
t0 = time.time() 

df = pd.DataFrame({'ser_no': [1, 1, 1, 2, 2, 2, 2, 3, 3, 3], 
        'CTRY_NM': ['a', 'a', 'b', 'e', 'e', 'a', 'b', 'b', 'b', 'd']}) 

df.replace(['^a$', '^b$', '^c$', '^d$', '^e$'], 
      ['America', 'Bahamas', 'Congo', 'Dominican Republic', 'Europe'], 
regex = True, inplace = True) 
tf = time.time() 
total = tf - t0 

Hier erhalten wir tf = 0.0019998, tf = 0.00200009, tf = 0.00200009 und tf = 0.00200009

So sieht es aus wie die Liste Version ersetzen ist schneller, aber immer noch auf große Datensätze ist es wirklich langsam. Irgendwelche Ideen?

+0

warum willst du es nicht auf einmal machen? – MaxU

+0

@MaxU Ich habe nie gesagt, ich wollte auch nicht. Es dauert nur zu lange, also versuche ich einen besseren Weg zu finden. – dustin

+0

Ich bin verwirrt. Sind diese alle in der gleichen Spalte? Sind sie zufällig im Datenrahmen verstreut? Ich denke, Sie möchten entlang der entsprechenden Achsen vektorisieren und auf nur die Spalten beschränken, die Sie eigentlich interessieren. Das sollte helfen, es zu beschleunigen, oder? – szeitlin

Antwort

1

Für die meisten Methoden, die in DataFrame vorhanden sind, gibt es eine Serie, die für eine Spalte funktioniert. Dies scheint nicht in der Dokumentation für 0,18 (noch!) Zu sein.

Das ist für mich gearbeitet:

df['CTRY_NM'].replace(to_replace=['^b','^c'], value=['America','Bahamas'], regex=True)

Sollte zumindest ein wenig schneller sein?

+1

Große Lösung. Es funktioniert in Bruchteilen der Zeit. – dustin

Verwandte Themen