Проблемы производительности python при использовании циклов с большими таблицами
Я использую python и несколько библиотек, таких как pandas и scipy, для подготовки данных, чтобы я мог начать более глубокий анализ. Для подготовки я, например, создаю новые столбцы с разницей в две даты.
Мой код дает ожидаемые результаты, но он очень медленный, поэтому я не могу использовать его для таблицы с 80-тысячными строками. Время выполнения займет около 80 минут на стол только для этой простой операции.
Проблема определенно связана с моей операцией записи:
tableContent[6]['p_test_Duration'].iloc[x] = difference
Кроме того, python выдает предупреждение:
полный пример кода для разницы дат:
import time
from datetime import date, datetime
tableContent[6]['p_test_Duration'] = 0
#for x in range (0,len(tableContent[6]['p_test_Duration'])):
for x in range (0,1000):
p_test_ZEIT_ANFANG = datetime.strptime(tableContent[6]['p_test_ZEIT_ANFANG'].iloc[x], '%Y-%m-%d %H:%M:%S')
p_test_ZEIT_ENDE = datetime.strptime(tableContent[6]['p_test_ZEIT_ENDE'].iloc[x], '%Y-%m-%d %H:%M:%S')
difference = p_test_ZEIT_ENDE - p_test_ZEIT_ANFANG
tableContent[6]['p_test_Duration'].iloc[x] = difference
правильная таблица результатов:
3 ответа
Уберите цикл и примените функции ко всей серии.
ZEIT_ANFANG = tableContent[6]['p_test_ZEIT_ANFANG'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S'))
ZEIT_ENDE = tableContent[6]['p_test_ZEIT_ENDE'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S'))
tableContent[6]['p_test_Duration'] = ZEIT_ENDE - ZEIT_ANFANG
Вы можете векторизовать преобразование дат, используя pd.to_datetime
и избегать использования apply
без необходимости.
tableContent[6]['p_test_Duration'] = (
pd.to_datetime(tableContent[6]['p_test_ZEIT_ENDE']) -
pd.to_datetime(tableContent[6]['p_test_ZEIT_ANFANG'])
)
Кроме того, вы получали SettingWithCopy
предупреждение из-за цепочки индексации
tableContent[6]['p_test_Duration'].iloc[x] = difference
Что вам не нужно беспокоиться, если вы поступите так, как я предложил.
Другие ответы хороши, но я бы порекомендовал вам вообще избегать цепной индексации. Документы pandas явно не рекомендуют цепную индексацию, поскольку она либо дает ненадежные результаты, либо медленна (из-за многочисленных обращений к __getitem__). Предполагая, что ваш фрейм данных многоиндексирован, вы можете заменить:
tableContent[6]['p_test_Duration'].iloc[x] = difference
с:
tableContent.loc[x, (6, 'p_test_Duration')] = difference
Иногда вы можете обойти эту проблему, но почему бы не изучить метод с наименьшей вероятностью вызвать проблемы в будущем?