У меня есть код, который я написал с помощью Pandas, который выполняет именно ту обработку, которую я хочу, но, к сожалению, работает медленно. Стремясь ускорить время обработки, я пошел по пути преобразования фрейма данных в список кортежей, где каждый кортеж представляет собой строку в фрейме данных.
Я обнаружил, что объекты datetime.datetime преобразуются в длинные целые числа, например 1622623719000000000.
Мне нужно рассчитать разницу во времени между каждой строкой, поэтому я подумал: «Хорошо, я не силен в python/pandas, но я знаю, что могу сделать datetime.fromtimestamp(1622623719000000000)
, чтобы вернуть объект datetime.
К сожалению, datetime.fromtimestamp(1622623719000000000)
выдает OSError: [Errno 22] Invalid argument
.
Итак, отправляйтесь в Google/SO, чтобы найти решение. Я нахожу этот пример, который показывает деление длинного целого числа на 1e3
. Я пытаюсь это сделать, но все равно получаю «неверный аргумент».
Я играю с делением длинного int, и деление на 1e9
дает мне самое близкое к исходному значению datetime.datetime, но не совсем.
Как успешно преобразовать long int обратно в правильное значение datetime?
Код для преобразования строкового формата в дату и время:
df.start_time = pd.to_datetime(df.report_date + " " + df.start_time)
Информация о кадре данных:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 46 entries, 0 to 45
Data columns (total 19 columns):
report_date 46 non-null object
...
...
...
start_time 46 non-null datetime64[ns]
...
...
...
dtypes: datetime64[ns](1), float64(7), int64(1), object(10)
memory usage: 6.9+ KB
None
Мой тестовый код:
print("DF start time", df.start_time[5], "is type", type(df.start_time[5]))
print("list start time", tup_list[5][7], "is type", type(tup_list[5][7]),"\n")
print("Convert long int in row tuple to datetime")
print(datetime.fromtimestamp(int(1622623719000000000/1e9)))
Вывод:
DF start time 2021-06-02 08:16:33 is type <class 'pandas._libs.tslibs.timestamps.Timestamp'>
list start time 1622623719000000000 is type <class 'int'>
Convert int in row tuple to datetime
2021-06-02 03:48:39
или, может быть, ваша индексация не очень хороша. Каковы значения до и после
Timestamp('2021-06-02 08:48:39')
в вашем фрейме данных?Я скопировал/вставил приведенный выше код, чтобы преобразовать столбец в
astype(int)
и получилTypeError: cannot astype a datetimelike from [datetime64[ns]] to [int32]
. Мой исходный код для преобразования из строкового формата в дату и время -df.start_time = pd.to_datetime(df.start_time)
Обновите свой код образцом исходного фрейма данных и выводом
df.info()
.Добавлено в соответствии с просьбой к исходному сообщению.
Какая у вас версия Python? Вы работаете на 32-битной машине (int32)? Если вы хотите решить проблему, я думаю, вам следует использовать
df['start_time'].astype(np.int64)
. Я могу воспроизвести вашу ошибку с помощью:df['start_time'].astype(np.int32)
Python версии 3.7, 64-разрядная версия. Я использовал
df['start_time'].astype(np.int64)
для созданияnumpy.int64
, и обратное преобразование в метку времени работает, когда я конвертируюdf.start_time
обратно вTimestamp
. Но, чтобы быстрее обрабатывать мою логику, я преобразовываю df в список кортежей черезdf.to_records(index=False).tolist()
Проблема, по-видимому, заключается в том, что когда строки df преобразуются в список кортежей,df.start_time
преобразуется из<class 'numpy.int64'>
в<class 'int'>
,1622621793000000000
в df (верно) на1622623719000000000
в кортеже (неверно).Мой метод недостаточно быстрый? Кажется, вы выполняете много операций (просмотр и индексация списка, которые могут быть медленными.
Ваш процесс в порядке, это моя обработка других данных в df, которая требует времени. Я только изучаю Pandas, и я знаю, что худшее, что вы можете сделать, это перебирать строки df, что я сейчас и делаю. Я поместил данные в df, чтобы получить из них работоспособный набор, а теперь преобразовал их обратно в список кортежей для более быстрой обработки путем повторения списка.