Как удалить те же значения, основанные на времени, используя интервал? - PullRequest
5 голосов
/ 11 мая 2019

У меня есть следующие данные:

Name |        Time     |   App 
---------------------------------
Mike  2019-05-10 21:10 chrome.exe
Mike  2019-05-10 21:10 chrome.exe
Mike  2019-05-10 21:12 chrome.exe
John  2019-05-10 18:09 chrome.exe
John  2019-05-10 18:25 chrome.exe

Моя цель заключается в следующем: я хочу объединить одни и те же приложения для каждого пользователя на основе одного и того же времени или с интервалом 5 минут и сохранить только самую раннюю временную отметку.

Ожидаемый результат:

Name |        Time     |   App 
---------------------------------
Mike  2019-05-10 21:10 chrome.exe
John  2019-05-10 18:09 chrome.exe
John  2019-05-10 18:25 chrome.exe

Майк пробежал chrome.exe 3 раза, но интервал был <= 5, поэтому мы хотим считать его как один раз. В то время как Джон пробежал <code>chrome.exe 2 раза, но> 5-минутный интервал, поэтому они считаются отдельными пробежками. Я пробовал merge, merge_asof и использую pd.timedelta.

Ответы [ 2 ]

3 голосов
/ 11 мая 2019

Давайте сначала создадим пример фрейма данных (немного отличающийся от вашего):

data = [('2019-01-01 13:00','John', 'Chrome'),('2019-01-01 13:02','John', 'Chrome'),('2019-01-01 13:06','John', 'Chrome'),('2019-01-01 13:00','Mike', 'Chrome'),('2019-01-01 13:02','Mike', 'Chrome'), ('2019-01-01 13:06','John', 'Chrome')]
df = pd.DataFrame(data, columns =['Time','Name','App'])

Вам понадобится время в качестве индекса в вашем фрейме данных. Вы можете достичь этого:

df.index = pd.to_datetime(df['Time'])

Тогда вы можете сделать следующее:

df.groupby(['Name', 'App', pd.Grouper(freq='5T')]).min() #5T here means 5 minutes

(обратите внимание, что это сгруппирует пятиминутные интервалы, начиная с полного часа, что означает, что 13:04 и 13:06 - это два разных случая, когда речь идет об этом решении). Вы можете искать различные частоты для группировки по http://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html

Результат:

Name  App     Time               
John  Chrome  2019-01-01 13:00:00    2019-01-01 13:00
              2019-01-01 13:05:00    2019-01-01 13:06
Mike  Chrome  2019-01-01 13:00:00    2019-01-01 13:00

Второй раз - это время, которое вас заинтересовало. Результат - pd.Series, вы, скорее всего, захотите сделать его фреймом данных или применить .unstack(level=1).

Как было отмечено в комментариях, вы не обязательно хотите указывать Time как индекс и новый столбец, тогда вместо df.index = pd.to_datetime(df.Time) вы можете захотеть сделать:

df.set_index('Time', inplace=True)
1 голос
/ 11 мая 2019

Вы можете попробовать это:

df['Time'] = pd.to_datetime(df['Time'])
print(df)
m = df.groupby(['Name','App']).Time.apply(lambda x: x.diff().dt.seconds < 5*60) #mask for 5 minutes
df2=df[~m]
print(df2)

Что такое m. Мы пытаемся удалить маску ваших дубликатов, но вместо того, чтобы удалить ее на месте, я просто назначил новый фрейм данных без этих строк.


   Name                Time          App
0  Mike 2019-05-10 21:10:00   chrome.exe
1  Mike 2019-05-10 21:10:00   chrome.exe
2  Mike 2019-05-10 21:12:00   chrome.exe
3  John 2019-05-10 18:09:00   chrome.exe
4  John 2019-05-10 18:25:00  chrome.exe7
   Name                Time          App
0  Mike 2019-05-10 21:10:00   chrome.exe
3  John 2019-05-10 18:09:00   chrome.exe
4  John 2019-05-10 18:25:00  chrome.exe7
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...