сгруппировать по фрейму данных по значениям, которые меньше, чем за секунду - pandas - PullRequest
0 голосов
/ 10 декабря 2018

Допустим, у меня есть пандасный фрейм данных, как показано ниже:

>>> df=pd.DataFrame({'dt':pd.to_datetime(['2018-12-10 16:35:34.246','2018-12-10 16:36:34.243','2018-12-10 16:38:34.216','2018-12-10 16:42:34.123']),'value':[1,2,3,4]})
>>> df
                       dt  value
0 2018-12-10 16:35:34.246      1
1 2018-12-10 16:36:34.243      2
2 2018-12-10 16:38:34.216      3
3 2018-12-10 16:42:34.123      4
>>> 

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

>>> df.groupby('dt',as_index=False)['value'].sum()
                       dt  value
0 2018-12-10 16:35:34.246      1
1 2018-12-10 16:36:34.243      2
2 2018-12-10 16:38:34.216      3
3 2018-12-10 16:42:34.123      4
>>> 

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

Мой желаемый выводэто:

                       dt  value
0 2018-12-10 16:35:34.246      3
1 2018-12-10 16:36:34.243      3
2 2018-12-10 16:38:34.216      3
3 2018-12-10 16:42:34.123      4

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Решение для грубой силы состоит в том, чтобы взять абсолютную разницу между серией datetime и каждым значением datetime, а затем сравнить с пороговым значением:

# data from @StephenCowley

threshold = pd.Timedelta(seconds=1)

df['val'] = [df.loc[(df['dt'] - t).abs() < threshold, 'value'].sum()
             for t in df['dt']]

print(df)

                       dt  value  val
0 2018-12-10 16:35:34.246      1    3
1 2018-12-10 16:35:34.243      2    3
2 2018-12-10 16:38:34.216      3    3
3 2018-12-10 16:42:34.123      4    4
0 голосов
/ 10 декабря 2018

(Предполагается, что вы имели в виду, что первые два имеют одинаковое значение минуты).

Я не уверен, как это сделать с groupby, но здесь что-то с теми же результатами:

df=pd.DataFrame({'dt':pd.to_datetime(['2018-12-10 16:35:34.246',
                                      '2018-12-10 16:35:34.243',
                                      '2018-12-10 16:38:34.216',
                                      '2018-12-10 16:42:34.123']),
                                      'value':[1,2,3,4]})

            # Select the rows that are greater than a second less
            # And less than a second more
            # Get their value columns and sum them
df['val'] = [df[(df.dt>t-pd.Timedelta(seconds=1))&
                (df.dt<t+pd.Timedelta(seconds=1))]['value'].sum()
             for t in df.dt]

                       dt  value  val
0 2018-12-10 16:35:34.246      1    3
1 2018-12-10 16:35:34.243      2    3
2 2018-12-10 16:38:34.216      3    3
3 2018-12-10 16:42:34.123      4    4

Как sidenote, я пытался сделать то же самое с groupby, но я не мог понять, как заставить его работать.Вы можете передать функцию в метод groupby.Если вы решите пойти по этому пути, обратите внимание, что функция заключается в получении индексов в Dataframe.Заставьте меня думать, что было бы трудно использовать groupby, так как я не знаю, что одна строка может принадлежать нескольким группам ...

...