Панды медленно заменяют фрейм данных

#python #excel #pandas #numpy #dataframe

#python #excel #pandas #numpy #фрейм данных

Вопрос:

У меня есть файл Excel (.xlsx) с примерно 800 строками и 128 столбцами с довольно плотными данными в сетке. Существует около 9500 ячеек, которые я пытаюсь заменить значениями ячеек с использованием фрейма данных Pandas:

 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() занимает 60 секунд. Есть ли способ ускорить это? Это не огромные данные или задача, я ожидал, что панды будут двигаться намного быстрее. К вашему сведению, я попытался выполнить ту же обработку с тем же файлом в CSV, но экономия времени была минимальной (около 50 секунд на replace() )

Комментарии:

1. from_filenames и to_filenames есть lists dicts ли?

2. @jezrael нет просто плоских списков строк. Значения ячеек

Ответ №1:

СТРАТЕГИИ
создайте pd.Series представление a map из имен файлов в имена файлов.
stack наш фрейм данных, map , затем unstack

настройка

 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)
  

решение

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

время

Фрейм данных 5 x 5

введите описание изображения здесь

100 x 100

введите описание изображения здесь

9500 x 800

введите описание изображения здесь

9500 x 800
map использование series vs dict
d = dict(zip(from_filenames, to_filenames))

введите описание изображения здесь

Ответ №2:

Я получил 60-секундную задачу для завершения за 10 секунд replace() , полностью удалив и используя set_value() по одному элементу за раз.

Ответ №3:

Я обнаружил, что создание нового столбца и удаление существующего столбца быстрее, чем ожидание вечно. 😉