Используйте это:
df.groupby('col1').apply(pd.DataFrame.sum,skipna=False).reset_index(drop=True)
#Or --> df.groupby('col1',as_index=False).apply(pd.DataFrame.sum,skipna=False)
Без apply()
благодаря @piRSquared:
df.set_index('col1').sum(level=0, min_count=1).reset_index()
благодаря @Alollz: если вы хотите вернуть сумму групп, содержащих NaN, а не просто NaNs
df.set_index('col1').sum(level=0,min_count=1).reset_index()
Выход
col1 col2
0 AAA 6.0
1 BBB 15.0
2 CCC NaN
Здесь ответили Как округлить время в T-SQL , и я думаю, что оно должно работать для вас.
CREATE FUNCTION [dbo].[RoundTime] (@Time datetime, @RoundTo float) RETURNS datetime
AS
BEGIN
DECLARE @RoundedTime smalldatetime, @Multiplier float
SET @Multiplier = 24.0 / @RoundTo
SET @RoundedTime= ROUND(CAST(CAST(CONVERT(varchar, @Time, 121) AS datetime) AS float) * @Multiplier, 0) / @Multiplier
RETURN @RoundedTime
END
-- Usage
SELECT dbo.RoundTime('13:15', 0.5)
create function RoundQuarterHour
(
@dt datetime
)
returns datetime
as
begin
declare @result datetime
declare @mm int
set @mm=datepart(minute,@dt)
set @result = dateadd(minute,-@mm + (round(@mm/cast(15 as float),0)*15) , @dt )
return @result
end
go
select dbo.RoundQuarterHour('2009-may-5 20:00') , '00'
union all select dbo.RoundQuarterHour('2009-may-5 20:01') , '01'
union all select dbo.RoundQuarterHour('2009-may-5 20:07') , '07'
union all select dbo.RoundQuarterHour('2009-may-5 20:08') , '08'
union all select dbo.RoundQuarterHour('2009-may-5 20:22') , '22'
union all select dbo.RoundQuarterHour('2009-may-5 20:23') , '23'
union all select dbo.RoundQuarterHour('2009-may-5 20:37') , '37'
union all select dbo.RoundQuarterHour('2009-may-5 20:38') , '38'
union all select dbo.RoundQuarterHour('2009-may-5 20:52') , '52'
union all select dbo.RoundQuarterHour('2009-may-5 20:53') , '53'
union all select dbo.RoundQuarterHour('2009-may-5 20:59') , '59'
Вы можете округлить дату до ближайшего квартала, например:
cast(floor(cast(getdate() as float(53))*24*4)/(24*4) as datetime)
Приведение даты-времени к двойному предшествованию чтобы избежать переполнения, double = float (53). Умножьте на 24 * 4 количество кварталов за день. Округлите до ближайшего кратного четверти с помощью floor (), а затем разделите на 24 * 4, чтобы преобразовать обратно в обычное время.
Time rounding in T-SQL is actually very problematic and many times inaccurate.
Years ago, I moved all rounding of times into code vs. using all the extra hub-bub one has to do in T-SQL to make it happen and to happen accurately. Rounding times in code is easier and much more accurate.
If you're stuck in T-SQL and have no supporting code, or don't have access to that code, then follow the examples previously mentioned. Otherwise, I humbly recommend letting code do the work.
Пробовал ответить Andomar, и возникли проблемы с округлением в 30 и 00 - так что несколько настроек, и это отлично работает:
cast(round(floor(cast(getdate() as float(53))*24*4)/(24*4),5) as smalldatetime)
Это покажет приращение за последние 15 минут, а не самое ближайшее, т.е. оно не будет продвигаться вперед, что мне и требовалось.
В настоящее время я использую вариант dateadd / dateiff с нулевой (0) датой для этого. Приведение не требуется:
select dateadd(minute, datediff(minute,0,GETDATE()) / 15 * 15, 0)
GETDATE () - это то, что у вас есть datetime.
Это будет работать для дат, по крайней мере, до 5500 года до того, как dateiff не сработает из-за переполнения. Однако, если вы попытаетесь использовать вторую точность, вышеуказанное сразу же не удастся.
Использование другой фиксированной даты, например «2009-01-01» или сегодняшней даты (предупреждение, более уродливый SQL), исправит это. Дата в будущем тоже подойдет. Если у него есть часть времени 00:00:00, вы можете основать на нем другое datetime.
например: округлить до ближайших 30 секунд:
select dateadd(second, round(datediff(second, '2010-01-01', GETDATE()) / 30.0, 0) * 30, '2010-01-01');
как насчет этого? (переменная добавлена для удобства чтения)
create function dbo.FloorTimeToQuarters
(
@dt as datetime
)
RETURNS datetime
as
BEGIN
DECLARE @timeAsInt bigint
SET @timeAsInt = ( cast( @dt as float ) * 96 )
RETURN DateAdd( hour, @timeAsInt % 96, cast( @timeAsInt / 96 as datetime) )
END
Попробуйте это:
Declare @Dt DateTime
Set @Dt = getDate()
Select DateAdd(minute,
15 * ((60 * Datepart(hour, @Dt) +
Datepart(Minute, @Dt)+
Case When DatePart(second, @Dt) < 30
Then 7 Else 8 End) / 15),
DateAdd(day, DateDiff(day, 0, @Dt), 0))