Почему время выполнения в python дает разные результаты при каждом запуске?

У меня есть кадр данных из одного столбца, имеющего положительные и отрицательные значения. Я хочу найти позицию индекса отрицательных значений. У меня есть два метода, и я пытаюсь найти лучший и самый быстрый. Мой код:

import pandas as pd
import time

df = pd.DataFrame({'Current': [1, 3, -4, 9, -3, 1, -2]})

# Method-1
start1 = time.time()
neg_index1 = df[(df["Current"]<0)].index.tolist()
print(neg_index1)
end1 = time.time()
print("Method-1 time is = ",end1 - start1)

# Method-2
start2 = time.time()
neg_index2 = df.iloc[df["Current"].lt(0).values].index.tolist()
print(neg_index2)
end2 = time.time()
print("Method-2 time is = ",end2 - start2)

Вывод при первом выполнении и метод 2 здесь быстрее:

[2, 4, 6]
Method-1 time is =  0.002000093460083008 
[2, 4, 6]
Method-2 time is =  0.0009999275207519531

Вывод при втором исполнении и, что интересно, оба часа в одно и то же время:

[2, 4, 6]
Method-1 time is =  0.0009999275207519531
[2, 4, 6]
Method-2 time is =  0.0009999275207519531

Результат при четвертом выполнении и, что удивительно, здесь быстрее, чем Метод 1:

[2, 4, 6]
Method-1 time is =  0.0009999275207519531
[2, 4, 6]
Method-2 time is =  0.0019998550415039062

Некоторое объяснение и помощь, чтобы узнать, какой метод быстрее?

Некоторое время зависит от других процессов, которые процессор будет запланирован операционной системой. поэтому, если есть другие процессы, вызываемые операционной системой, и ваши процессоры заняты, возникает ситуация такого типа.

durjoy 10.09.2018 07:40

вы можете запустить это в виртуальном env и посмотреть, изменит ли он время выполнения, поскольку ресурсы будут гораздо более сфокусированными по сравнению с не виртуальным env.

Anil_M 10.09.2018 07:42

Не используйте time.time для тестирования вещей; используйте модуль timeit. Для этого есть ряд веских причин, но трудно превзойти тот факт, что вы пытаетесь измерить что-то, что занимает 1-2 мс, с часами с разрешением 1 мс, что означает, что у вас есть планки ошибок +/-. 100%…

abarnert 10.09.2018 07:43

@durjoy, Рад получить ваши отзывы. Из-за того, что я не работал на компьютере, я не понял, о чем здесь говорится. Пожалуйста, помогите мне с кодом.

Msquare 10.09.2018 07:45

@Anil_M, Рад получить ваши отзывы. Из-за того, что я не работал на компьютере, я не понял, о чем здесь говорится. Пожалуйста, помогите мне с кодом

Msquare 10.09.2018 07:45

@abarnert, как пользоваться функцией timeit? Какой-нибудь код, пожалуйста?

Msquare 10.09.2018 07:46

Если вы не можете понять примеры в документах, на которые я ссылался, я понятия не имею, что я мог бы добавить в комментарий StackOverflow, который мог бы помочь.

abarnert 10.09.2018 07:49

@Msquare np.where - самый быстрый (безусловно)

U11-Forward 10.09.2018 07:49

@Msquare Мой ответ запускается десять раз с timeit

U11-Forward 10.09.2018 07:50
0
10
390
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я бы предпочел использовать np.where:

np.where(df['Current']<0)[0].tolist()

Также не используйте time.time, используйте timeit:

import pandas as pd, numpy as np
import timeit

df = pd.DataFrame({'Current': [1, 3, -4, 9, -3, 1, -2]})

# Method-1
neg_index1 = df[(df["Current"]<0)].index.tolist()
print(neg_index1)
print("Method-1 time is = ",timeit.timeit(lambda: df[(df["Current"]<0)].index.tolist(),number=10))

# Method-2
neg_index2 = df.iloc[df["Current"].lt(0).values].index.tolist()
print(neg_index2)
print("Method-2 time is = ",timeit.timeit(lambda: df.iloc[df["Current"].lt(0).values].index.tolist(),number=10))

# Method-3
neg_index2 = np.where(df['Current']<0)[0].tolist()
print(neg_index2)
print("Method-3 time is = ",timeit.timeit(lambda: np.where(df['Current']<0)[0].tolist(),number=10))

Выход:

[2, 4, 6]
Method-1 time is =  0.0211404744016608
[2, 4, 6]
Method-2 time is =  0.02377961247025239
[2, 4, 6]
Method-3 time is =  0.007515077367731743

Итак, np.where побеждает!

Превосходно. Вы просто великолепны, что познакомили меня с новым методом-3. Я выполнял это много раз. Вы на месте, и это быстрее всех. Большое спасибо.

Msquare 10.09.2018 07:53

Не могли бы вы дать мне какое-нибудь объяснение относительно [0] в np.where(df['Current']<0)[0]. Я имею в виду, к чему это относится?

Msquare 10.09.2018 07:56

@Msquare numpy.where возвращает (в данном случае) (array([2, 4, 6], dtype=int64),) (кортеж), поэтому получите первый (нулевой) элемент, затем выполните tolist

U11-Forward 10.09.2018 07:56

Это был не мой вопрос. У меня вопрос: зачем нам использовать [0] в конце np.where(df['Current']<0)[0]?

Msquare 10.09.2018 07:58

@Msquare Вам нужно, потому что np.where возвращает кортеж только с одним элементом (массивом), поэтому получите первый (нулевой) элемент

U11-Forward 10.09.2018 07:59

Я понял. Спасибо

Msquare 10.09.2018 08:10

@Msquare Рады, что вы понимаете, 😊😊

U11-Forward 10.09.2018 08:12

Что произойдет, если мы поместим [1] вместо [0] в конец кортежа? Я имею в виду, это правда?

Msquare 10.09.2018 08:20

@Msquare Тогда это вызовет ошибку: IndexError: tuple index out of range

U11-Forward 10.09.2018 08:23

1. print("\n\n",np.where(df['Current']<0)), вывод: (array([2, 4, 6], dtype=int64),) Это кортежный вывод? Я прав ?, 2. Вывод print(np.where(df['Current']<0)[0]): [2 4 6] Какой тип / имя этого вывода? 3. print(np.where(df['Current']<0)[0].tolist()) Выход: [2,4,6]. Это список. Я понял.

Msquare 10.09.2018 08:26

@Msquare Что вы имеете в виду под названием?

U11-Forward 10.09.2018 08:27

Я имею в виду, что это за тип данных этого вывода?

Msquare 10.09.2018 08:29

@Msquare это список

U11-Forward 10.09.2018 08:30
[2,4,6] Надеюсь! это список. Но у [2 4 6] нет , между значениями. Это все еще список?
Msquare 10.09.2018 08:32

@Msquare Нет, это массивный массив

U11-Forward 10.09.2018 08:33

Да, это то, о чем я хотел спросить. Хороший. Я понял. Теперь (array([2, 4, 6], dtype=int64),) - это кортеж. [2 4 6] - это массивный массив. [2,4,6] - это список. Я прав?

Msquare 10.09.2018 08:35

Спасибо, что научили меня этой маленькой и базовой теме. Я начал изучать питон месяц назад. Я узнал разницу между этими тремя здесь. Большое спасибо за ваше терпение. Мне интересно! как вы научились этим трюкам с питоном? каков ваш источник обучения? сколько времени вам понадобилось, чтобы достичь этой стадии?

Msquare 10.09.2018 08:38

Извините за поздний ответ, я кое-чему научился от учебная точка, мне потребовалось около года, чтобы добраться до этого этапа, но также мне очень помогли другие люди вокруг меня, также многому научился у stackoverflow, видя другие ответы, Также я учусь, отвечая на вопросы, надеюсь, что это поможет

U11-Forward 10.09.2018 09:08

Пока вы измеряете время, затрачиваемое на каждое выполнение, могут быть другие процессы, потребляющие ресурсы. Также может быть, что сборщик мусора вмешивается в случайные моменты, искажая результаты. Поэтому никогда не используйте time.time() для сравнения производительности.

Используйте timeit.timeit для измерения производительности. Он повторяет запуск кода несколько раз и измеряет среднее время, затрачиваемое на каждый запуск, таким образом обеспечивая более точные результаты. Он также отключает сборку мусора во время выполнения.

Другие вопросы по теме