Поскольку вы хотите просто перенести это на Python и не настраивать Pandas, в частности, я выбрал подход, не связанный с Pandas. Я использовал ваши примеры строк и сделал 47124
строк за 0.182
секунд.
Pandas действительно хорош и интуитивно понятен для некоторых случаев использования, но может быть очень медленным для итерации. Эта страница объясняет некоторые из медленных применений Панд, одним из которых является в основном итерация индекса. Одним из способов сделать это было бы использование 5. Vectorization with NumPy arrays
, но ваш вариант использования выглядит достаточно простым, чтобы это могло быть излишним и не стоило бы этого (учитывая, что вас зовут PythonNoob).
Ради ясности и скорости простое использование более простых функций Python может дать вам желаемую скорость.
Сначала я установил константы
percent_monitor = .03
warming_factor = 1 - percent_monitor
cooling_factor = 1 + percent_monitor
Затем (для простоты использования есть более чистые способы сделать это, но это очень ясно) Я задаю имена столбцов, соответствующие значениям столбцов:
DATE = 0
TEMP = 1
MONITOR = 2
TRENDING = 3
CHANGE_IN_TREND = 4
Затем я вытащил код вашего монитора в его собственную функцию (и немного почистил if
-выступления:
def calculate_monitor(prev_monitor, current_temp, prev_temp):
if (current_temp > prev_monitor) and (current_temp > prev_temp) and (current_temp * warming_factor) > prev_monitor:
return current_temp * warming_factor
elif (current_temp < prev_monitor) and ((current_temp * cooling_factor) < prev_monitor):
return current_temp * cooling_factor
else:
return prev_monitor
Наконец, я прочитал код и обработал его:
data = [] # I am going to append everything to this
with open('weather_data.csv') as csv_file:
previous_row = None
csv_reader = csv.reader(csv_file, delimiter=' ')
line_count = 0
for row in csv_reader:
cleaned_row = list(filter(None, row))
if line_count == 0:
# first row is column -- I am leaving it blank you can do whatever you want with it
line_count += 1
elif line_count == 1: # this is the first line
previous_row = cleaned_row + [float(cleaned_row[TEMP]) * warming_factor, "warming", False]
data.append(previous_row)
line_count += 1
else:
monitor = calculate_monitor(float(previous_row[MONITOR]), float(cleaned_row[TEMP]), float(previous_row[TEMP]))
current_trend = 'warming' if float(cleaned_row[TEMP]) > float(previous_row[MONITOR]) else 'cooling'
change_in_trend = False if current_trend != previous_row[CHANGE_IN_TREND] else True
previous_row = cleaned_row + [monitor, current_trend, change_in_trend]
data.append(previous_row)
line_count += 1
Это даст вам необходимую скорость. Если вы хотите преобразовать это в кадр данных pandas в конце, вы можете сделать:
df = pd.DataFrame(data, columns=['date', 'temp', 'monitor', 'current_trend', 'change_in_trend'])