#python
#python
Вопрос:
Я новичок в Python и столкнулся с проблемой.
У меня есть фрейм данных, где один из столбцов — это время отправления рейсов. Эти часы приведены в следующем формате: 1100.0, 525.0, 1640.0 и т.д.
Это серия pandas, которую я хочу преобразовать в серию datetime, такую как : S = [11.00, 5.25, 16.40,...]
Что я уже пробовал :
- Преобразование моих объектов в строку :
S = [str(x) for x in S]
- Использование datetime.strptime :
S = [datetime.strptime(x,'%H%M.%S') for x in S]
Но поскольку они не все имеют одинаковый формат, это не работает
- Использование синтаксического анализатора из dateutil :
S = [parser.parse(x) for x in S]
Я получил ошибку :
'Unknown string format'
- Использование panda datetime :
S= pd.to_datetime(S)
Не дает мне ожидаемого результата
Спасибо за ваши ответы!
Комментарии:
1. Почему бы вам не
split
указать точку, а затем проверить длину строки? Если это 3, то сделайтеdatetime (0,0,0,int(srting_before_point[0]),int(string_before_point[-2:]),after_point_string)
и что-то подобное, если длина равна 4.2. можете ли вы показать нам пример, который
datetime.strptime(x,'%H%M.%S')
не работает?3. @Nerdrigo Не было бы намного проще просто разделить каждый элемент на 100?
4. Итак, это изначально числа с плавающей запятой? Почему бы просто не выполнить простую математику, чтобы разделить часы и минуты, а затем передать эти числа конструктору datetime. Я не вижу никаких причин выполнять здесь операции со строками.
5. Не решение, а способ нормализовать форматы:
s = [f'{x:07.2f}' for x in s]
. Это сделаетs = ['1100.00', '0525.00', '1640.00']
дляs = [1100.0, 525.0, 1640.0]
.
Ответ №1:
Поскольку это столбцы внутри фрейма данных (A series
), оставьте его таким, пока преобразование должно работать просто отлично.
S = [1100.0, 525.0, 1640.0]
se = pd.Series(S) # Your column
# se:
0 1100.0
1 525.0
2 1640.0
dtype: float64
setime = se.astype(int).astype(str).apply(lambda x: x[:-2] ":" x[-2:])
Это преобразует числа с плавающей точкой в правильно отформатированные строки:
0 11:00
1 5:25
2 16:40
dtype: object
И тогда вы можете просто сделать:
df["your_new_col"] = pd.to_datetime(setime)
Ответ №2:
Как насчет этого?
(Добавлен оператор if, поскольку некоторые записи содержат 4 цифры перед десятичной дробью, а некоторые — 3. Добавлен вариант использования 125.0 для учета этого)
from datetime import datetime
S = [1100.0, 525.0, 1640.0, 125.0]
for x in S:
if str(x).find(".")==3:
x="0" str(x)
print(datetime.strftime(datetime.strptime(str(x),"%H%M.%S"),"%H:%M:%S"))
Ответ №3:
Вы могли бы попробовать это следующим образом:
# Just initialising a state in line with your requirements
st = ["1100.0", "525.0", "1640.0"]
dfObj = pd.DataFrame(st)
# Casting the string column to float
dfObj_num = dfObj[0].astype(float)
# Getting the hour representation out of the number
df1 = dfObj_num.floordiv(100)
# Getting the minutes
df2 = dfObj_num.mod(100)
# Moving the minutes on the right-hand side of the decimal point
df3 = df2.mul(0.01)
# Combining the two dataframes
df4 = df1.add(df3)
# At this point can cast to other types
Результат:
0 11.00
1 5.25
2 16.40
Вы можете запустить этот пример, чтобы проверить шаги для себя, также вы можете превратить его в функцию. При необходимости внесите небольшие изменения, чтобы настроить его в соответствии с вашими точными требованиями.
Может быть полезно ознакомиться с этой статьей о серии Pandas. https://www.geeksforgeeks.org/python-pandas-series /
Ответ №4:
Должен быть лучший способ сделать это, но у меня это работает.
df=pd.DataFrame([1100.0, 525.0, 1640.0], columns=['hour'])
df['hour_dt']=((df['hour']/100).apply(str).str.split('.').str[0] '.'
df['hour'].apply((lambda x: '{:.2f}'.format(x/100).split('.')[1])).apply(str))
print(df)
hour hour_dt
0 1100.0 11.00
1 525.0 5.25
2 1640.0 16.40