Реализация счетчика посетителя

Numpy и Pandas используют разные алгоритмы для isin. В некоторых случаях версия Numpy быстрее, а для некоторых панд. Для вашего теста NumPy кажется быстрее.

Версия Pandas, однако, имеет лучшее асимптотическое время выполнения, она выиграет для больших наборов данных.


Предположим, что в серии данных есть n элементов (в вашем примере df) и в запросе m (в вашем примере vals).

Обычно алгоритм Numpy выполняет следующие действия:

  • Используйте np.unique(..), чтобы найти все уникальные элементы в ряду. Таким образом, выполняется сортировка, т. Е. O(n*log(n)), может быть N<=n уникальных элементов.
  • Для каждого элемента используйте бинарный поиск, чтобы определить, входит ли элемент в ряд, то есть O(m*log(N)) в целом.

Что приводит к общему времени работы O(n*log(n) + m*log(N)).

Существуют некоторые жестко запрограммированные оптимизации для случаев, когда vals только несколько элементов, и для этих случаев действительно блестит numpy.

Панды делают что-то другое:

  • Заполняет хеш-карту (обернутая khash -функция), чтобы найти все уникальные элементы, которая занимает O(n).
  • Поиск в хэш-карте в O(1) для каждого запроса, т. Е. O(m) в целом.

В целом, время работы составляет O(n)+O(m), что намного лучше, чем у Нампи.

Однако, для меньших входных данных постоянные факторы, а не асимптотическое поведение - это то, что имеет значение, и это просто намного лучше для Numpy. Есть и другие соображения, такие как потребление памяти (которое выше у панд), которое может сыграть свою роль.

Но если мы возьмем больший набор запросов, ситуация будет совершенно другой:

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0,10,(10**6),dtype='int8'),columns=['A'])
vals = np.array([5,7],dtype='int64')
vals2 = np.random.randint(0,10,(10**6),dtype='int64')

И теперь:

%timeit df['A'].isin(vals)    # 17.0 ms 
%timeit df['A'].isin(vals2)   # 16.8 ms

%timeit pd.np.in1d(df['A'],vals)    # 1.36
%timeit pd.np.in1d(df['A'],vals2)   # 82.9 ms

Numpy действительно сдает позиции, пока есть больше запросы. Также можно видеть, что создание хеш-карты является узким местом для панд, а не для запросов.

В конце концов, не имеет большого смысла (даже если бы я это сделал!) Оценивать производительность только для одного размера ввода - это должно быть сделано для диапазона размеров ввода - есть некоторые сюрпризы, которые нужно обнаружить!

Например, Интересный факт: если вы возьмете

df = pd.DataFrame(np.random.randint(0,10,(10**6+1), dtype='int8'),columns=['A'])

, т.е. 10^6+1 вместо 10^6, панды прибегнут к алгоритму numpy (который, на мой взгляд, не очень умен) и станут лучше для маленьких входов, но хуже для больших:

%timeit df['A'].isin(vals)    # 6ms  was 17.0 ms 
%timeit df['A'].isin(vals2)   # 100ms was 16.8 ms
5
задан LalitBarik 21 March 2009 в 09:45
поделиться

4 ответа

Аналитический сценарий Google точно, в чем Вы нуждаетесь. Поскольку сессия, будет открываться для поисковых роботов также.

1
ответ дан 13 December 2019 в 19:36
поделиться

Я могу только предложение второго Gareth для использования уже доступного анализа трафика. Если Вам не нравится идея дать данные Google по трафику Вашего веб-сайта, можно также загрузить файлы журнала и проанализировать их с одним из многих аналитических доступных инструментов файла журнала веб-сервера.

1
ответ дан 13 December 2019 в 19:36
поделиться

Используйте Google Analytics. Не пытайтесь изобрести велосипед если a) колесо не делает то, что Вы хотите или b) Вы просто пытаетесь узнать, как колесо работает

3
ответ дан 13 December 2019 в 19:36
поделиться

Для наивной реализации можно использовать пользовательский HttpModule. Для каждого запроса к Вашему приложению Вы были бы:

  1. Проверьте если Запрос. Cookie включают Cookie Отслеживания
  2. Если cookie отслеживания не существует, это - вероятно, новый посетитель (или иначе, их cookie истек - см. 4.)
  3. Для нового посетителя зарегистрируйте статистику посетителя, затем обновите количество посетителя
  4. Добавьте cookie отслеживания к ответу, передаваемому обратно посетителю. Вы захотите установить этот cookie, чтобы иметь довольно долгий период истечения, таким образом, Вы не получите много "ложных положительных сторон" с возвращающимися пользователями, cookie которых истекли.

Вот некоторый скелетный код ниже (сохраните как StatsCounter.cs):

using System;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Transactions;

namespace hitcounter
{
    public class StatsCounter : IHttpModule
    {
        // This is what we'll call our tracking cookie.
        // Alternatively, you could read this from your Web.config file:
        public const string TrackingCookieName = "__SITE__STATS";

        #region IHttpModule Members

        public void Dispose()
        { ;}

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
            context.PreSendRequestHeaders += new EventHandler(context_PreSendRequestHeaders);
        }

        void context_PreSendRequestHeaders(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            HttpResponse response = app.Response;
            if (response.Cookies[TrackingCookieName] == null)
            {
                HttpCookie trackingCookie = new HttpCookie(TrackingCookieName);
                trackingCookie.Expires = DateTime.Now.AddYears(1);  // make this cookie last a while
                trackingCookie.HttpOnly = true;
                trackingCookie.Path = "/";
                trackingCookie.Values["VisitorCount"] = GetVisitorCount().ToString();
                trackingCookie.Values["LastVisit"] = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss");

                response.Cookies.Add(trackingCookie);
            }
        }

        private long GetVisitorCount()
        {
            // Lookup visitor count and cache it, for improved performance.
            // Return Count (we're returning 0 here since this is just a stub):
            return 0;
        }

        void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            HttpRequest request = app.Request;

            // Check for tracking cookie:
            if (request.Cookies[TrackingCookieName] != null)
            {
                // Returning visitor...
            }
            else
            {
                // New visitor - record stats:
                string userAgent = request.ServerVariables["HTTP_USER_AGENT"];
                string ipAddress = request.ServerVariables["HTTP_REMOTE_IP"];
                string time = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss");
                // ...
                // Log visitor stats to database

                TransactionOptions opts = new TransactionOptions();
                opts.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, opts))
                {
                    // Update visitor count.
                    // Invalidate cached visitor count.
                }
            }
        }

        #endregion
    }
}

Зарегистрируйте этот модуль путем добавления следующих строк к файлу Web.config:

<?xml version="1.0"?>
<configuration>
    ...
    <system.web>
        ...
        <httpModules>
          <add name="StatsCounter" type="<ApplicationAssembly>.StatsCounter" />
        </httpModules>
    </system.web>
</configuration>

(Замена названием Вашего проекта веб-приложения, или удаляют его, если Вы используете проект Веб-сайта.

Хотелось бы надеяться, этого будет достаточно для получения Вас, начал экспериментировать. Как другие указали, хотя для фактического сайта Вы - очень более обеспеченный Google использования (или некоторый другой) решение для аналитики для этого.

6
ответ дан 13 December 2019 в 19:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: