2016-10-04 17 views
5

Mam plik Excel (.xlsx) z około 800 wierszy i 128 kolumnami z dość gęstymi danymi w siatce. Istnieje około 9500 komórek, które staram się zastąpić wartości komórek z użyciem pandy ramkę danych:Pandy powolne na ramce danych zastępują

xlsx = pandas.ExcelFile(filename) 
frame = xlsx.parse(xlsx.sheet_names[0]) 
media_frame = frame[media_headers] # just get the cols that need replacing 

from_filenames = get_from_filenames() # returns ~9500 filenames to replace in DF 
to_filenames = get_to_filenames() 

media_frame = media_frame.replace(from_filenames, to_filenames) 
frame.update(media_frame) 
frame.to_excel(filename) 

replace() trwa 60 sekund. Jakikolwiek sposób przyspieszyć to? To nie są wielkie dane ani zadania, spodziewałem się, że pandy będą poruszać się znacznie szybciej. FYI Próbowałem robić tę samą obróbkę z tego samego pliku w formacie CSV, ale oszczędność czasu był minimalny (około 50 sekund na replace())

+0

'from_filenames' oraz' to_filenames' to 'list'' dykts'? – jezrael

+0

@jezrael nie tylko płaskie listy ciągów znaków. Wartości komórek – Neil

Odpowiedz

6

strategy
tworzyć pd.Series reprezentujący map z nazwami do nazw plików.
stack nasz dataframe, map, następnie unstack

setup

import pandas as pd 
import numpy as np 
from string import letters 

media_frame = pd.DataFrame(
    pd.DataFrame(
     np.random.choice(list(letters), 9500 * 800 * 3) \ 
      .reshape(3, -1)).sum().values.reshape(9500, -1)) 

u = np.unique(media_frame.values) 
from_filenames = pd.Series(u) 
to_filenames = from_filenames.str[1:] + from_filenames.str[0] 

m = pd.Series(to_filenames.values, from_filenames.values) 

rozwiązanie

media_frame.stack().map(m).unstack() 

czas

5 x 5 dataframe

enter image description here

100 x 100

enter image description here

9500 x 800

enter image description here

9500 x 800
map pomocą series vs dict
d = dict(zip(from_filenames, to_filenames))

enter image description here

1

Mam 60 sekund zadania, aby ukończyć w 10 sekund, usuwając replace() łącznie i przy użyciu set_value() jeden element na raz.