Pandas-Dataframe: как подсчитать, сколько раз переменная повторяется за 1 минуту

#python-3.x #pandas #datetime #dataframe #pandas-groupby

#python-3.x #pandas #дата-время #фрейм данных #pandas-groupby

Вопрос:

У меня есть следующий фрагмент фрейма данных:

 Full dataframe:                   ip      time      cik  crawler
ts                                                              
2019-03-11 00:00:01   71.155.177.ide  00:00:01  1262327      0.0
2019-03-11 00:00:02   71.155.177.ide  00:00:02  1262329      0.0
2019-03-11 00:00:05   69.243.218.cah  00:00:05   751200      0.0
2019-03-11 00:00:08  172.173.121.efb  00:00:08   881890      0.0
2019-03-11 00:00:09   216.254.60.idd  00:00:09  1219169      0.0
2019-03-11 00:00:09    64.18.197.gjc  00:00:09  1261705      0.0
2019-03-11 00:00:09    64.18.197.gjc  00:00:09  1261734      0.0
2019-03-11 00:00:10    64.18.197.gjc  00:00:10  1263094      0.0
2019-03-11 00:00:10    64.18.197.gjc  00:00:10  1264242      0.0
2019-03-11 00:00:10    64.18.197.gjc  00:00:10  1264242      0.0
  

Я хочу сгруппировать по IP-адресам, а затем использовать некоторую функцию для подсчета:

1) Сколько уникальных ссылок приходится на IP за 1 минуту

2) Сколько CIK’ов (всего) приходится на IP-адрес за 1 минуту.

Я пробовал функцию повторной выборки, но я не знаю, как заставить ее считать так, как я хочу. Мой код следующий:

 dataframe = pd.read_csv(path   "log20060702.csv", usecols=['cik', 'ip', 'time', 'crawler'])
dataframe = dataframe[dataframe['crawler'] == 0]
dataframe['cik'] = pd.to_numeric(dataframe['cik'], downcast='integer')
dataframe['ts'] = pd.to_datetime((dataframe['time']))

dataframe = dataframe.set_index(['ts'])
print("Full dataframe: ", dataframe.head(10))

df_dict = dataframe.groupby("ip")
counter = 0
for key, df_values in df_dict:
    counter  = 1
    print("df values: ", df_values)
    # df_values = df_values.resample("5T").count()
    if counter == 5:
        break
  

Или, если кто-нибудь может сказать мне, как я могу группировать по IP и каждые 1 минуту, а остальное я могу сделать сам. Я не обязательно ищу полное решение, некоторые рекомендации были бы очень признательны.

Ответ №1:

Используйте groupby с DataFrameGroupBy.resample и агрегируйте SeriesGroupBy.nunique с count by DataFrameGroupBy.size :

 df = dataframe.groupby("ip").resample('1Min')['cik'].agg(['nunique','size'])
print (df)
                            nunique  size
ip              ts                       
172.173.121.efb 2019-03-11        1     1
216.254.60.idd  2019-03-11        1     1
64.18.197.gjc   2019-03-11        4     5
69.243.218.cah  2019-03-11        1     1
71.155.177.ide  2019-03-11        2     2
  

Или используйте Grouper :

 df = dataframe.groupby(["ip", pd.Grouper(freq='1Min')])['cik'].agg(['nunique','size'])
print (df)
                            nunique  size
ip              ts                       
172.173.121.efb 2019-03-11        1     1
216.254.60.idd  2019-03-11        1     1
64.18.197.gjc   2019-03-11        4     5
69.243.218.cah  2019-03-11        1     1
71.155.177.ide  2019-03-11        2     2
  

Комментарии:

1. .resample('1Min') Возвращает size значение в минуту в этом случае?

2. @Erfan — да, именно.

3. Довольно аккуратно, вам не нужно явно указывать datetime столбец в этом случае. Как бы это работало, если бы было несколько столбцов datetime? @jezrael

4. @Erfan — нужен один, лучший по melt