Введение в анализ данных с помощью Python Часть 3: Анализ данных с помощью Pandas и NumPy с Python

  • Введение
  • Шаг 1. Импорт Pandas и NumPy
  • Шаг 2. Импорт из Excel
  • Шаг 3. Проверка данных
    • Шаг 3.1. Как выглядят данные
    • Шаг 3.2. Проверка типов данных столбцов
    • Шаг 3.3. Проверка наличия значений NaN (Null)
  • Шаг 4. Основные функции анализа в Pandas
    • Шаг 4.1. Общее количество заказов
    • Шаг 4.2. Показать заказы с общей суммой более 50 фунтов стерлингов
    • Шаг 4.3. Показать заказ с наибольшей стоимостью
    • Шаг 4.4. Показать заказы с наименьшей стоимостью
  • Шаг 5. Группировка данных по критериям
    • Шаг 5.1. Общее количество заказов по валюте
    • Шаг 5.2. Общее количество заказов по полу
    • Шаг 5.3. Общая стоимость заказов по полу
  • Шаг 6. Использование среднего значения
    • Шаг 6.1. Получите среднее значение всех заказов
    • Шаг 6.2. Получите среднее значение заказов по странам
    • Шаг 6.3. Получить среднее значение заказов по стране, городу и полу
  • Шаг 7. Использование медианы
    • Шаг 7.1. Получите медиану заказов по странам
    • Шаг 7.2. Получение медианы заказов по стране, городу и полу
  • Шаг 8. Работа с датами
    • Шаг 8.1. Пересоздайте индекс для фрейма данных с датами для индекса
    • Шаг 8.2. Определите итоговые суммы заказов за день в определенном диапазоне
    • Шаг 8.3. Показать общее количество заказов и среднее значение для каждого года
    • Шаг 8.4. Показать общее количество заказов и среднее значение за один год
    • Шаг 8.5. Показать общую стоимость заказов и среднее значение по месяцам за каждый год
  • Ресурсы
Содержание
  1. Введение
  2. Шаг 1. Импорт Pandas и NumPy
  3. Шаг 2. Импорт из Excel
  4. Шаг 3. Проверка данных
  5. Шаг 3.1. Как выглядят данные
  6. Шаг 3.2. Проверка типов данных столбцов
  7. Шаг 3.3. Проверка на наличие значений NaN (Null)
  8. Шаг 4. Основные функции анализа с помощью Pandas
  9. Шаг 4.1. Общее количество заказов
  10. Шаг 4.2. Показать заказы с суммой более 50 фунтов стерлингов
  11. Шаг 4.3. Показать порядок наибольшего значения
  12. Шаг 4.4. Показать заказ с наименьшим значением
  13. Шаг 5. Группировка данных по критериям
  14. Шаг 5.1. Общее количество заказов по валюте
  15. Шаг 5.2. Общее количество заказов по полу
  16. Шаг 5.3. Общая стоимость заказов по полу
  17. Шаг 6. Использование среднего значения
  18. Шаг 6.1. Получение среднего значения всех заказов
  19. Шаг 6.2. Получение среднего количества заказов по странам
  20. Шаг 6.3. Получение среднего количества заказов по стране, городу и полу
  21. Шаг 7. Использование медианы
  22. Шаг 7.1. Получение медианы заказов по странам
  23. Шаг 7.2. Получение медианы заказов по стране, городу и полу
  24. Шаг 8. Работа с датами
  25. Шаг 8.1. Воссоздайте индекс для фрейма данных с датами для индекса
  26. Шаг 8.2. Вычислите итоговые суммы заказов за день в определенном диапазоне
  27. Шаг 8.3. Показать общее количество заказов и среднее значение для каждого года
  28. Шаг 8.4. Показать общие значения заказов и среднее значение для одного года
  29. Шаг 8.5. Показать общее количество заказов и среднее значение по месяцам для каждого года
  30. Ресурсы

Введение

В этой серии статей, состоящей из нескольких частей, я рассмотрю некоторые основы Pandas, NumPy и Matplotlib, которые я изучил за последние несколько недель.

В первой части я рассмотрел следующие темы:

  • Импорт данных из CSV-файла в Pandas
  • Очистка данных и удаление непригодных данных.
  • Преобразование между типами данных.
  • Экспорт и импорт данных в файлы Excel и из них.

Во второй части я рассказал о выполнении математических операций над данными, хранящимися во фрейме данных, с помощью Pandas и NumPy.

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

Как и в предыдущих частях, блокнот Jupyter, а также все остальные необходимые файлы находятся в репозитории GitHub, ссылка на который есть в разделе «Ресурсы».

Давайте приступим к третьей части.

Шаг 1. Импорт Pandas и NumPy

Прежде всего, необходимо импортировать библиотеки Pandas и NumPy.

import pandas as pd
import numpy as np
Войдите в полноэкранный режим Выйти из полноэкранного режима

Шаг 2. Импорт из Excel

После импорта библиотек следующим шагом будет импорт данных. При импорте данных будет использоваться строгое соблюдение типа данных, как и во второй части, когда импортировался лист Excel.

Единственное отличие в том, что в этот раз нужно импортировать больше столбцов, а строки пропускать не придется.

sales_data = pd.read_excel(io = "data/order_data_with_totals.xlsx",
                           sheet_name = "order_data_with_totals",
                           dtype      = {"order_id": np.int64,
                                         "order_date": "datetime64",
                                         "customer_id": np.int64, 
                                         "customer_first_name": str,
                                         "customer_last_name": str,
                                         "customer_gender": str,
                                         "customer_city": str,
                                         "customer_country": str,
                                         "item_description": str,
                                         "item_qty": np.int64,
                                         "item_price": np.float64,
                                         "order_currency": str,
                                         "order_vat_rate": np.float64,
                                         "order_total_ex_vat_local_currency": np.float64,
                                         "order_total_vat_local_currency": np.float64,
                                         "order_total_inc_vat_local_currency": np.float64,
                                         "order_currency_conversion_rate": np.float64,
                                         "order_total_ex_vat_converted_gbp": np.float64,
                                         "order_total_vat_converted_gbp": np.float64,
                                         "order_total_inc_vat_converted_gbp": np.float64})
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 3. Проверка данных

Теперь, когда данные были импортированы из файла Excel во фрейм sales_data, давайте посмотрим на содержащиеся в нем данные.

Шаг 3.1. Как выглядят данные

Сначала посмотрим на первые пять строк данных в рамке данных sales_data.

sales_data.head(n = 5)
Войти в полноэкранный режим Выход из полноэкранного режима

Главное отличие на этот раз заключается в том, что справа от рамки данных sales_data появилось больше столбцов. Я показал только некоторые из них, так как изображение не поместилось бы со всеми столбцами, которые есть в кадре данных sales_data.

Шаг 3.2. Проверка типов данных столбцов

Далее давайте посмотрим на типы данных, которые были назначены каждому столбцу в рамке данных sales_data.

sales_data.dtypes
Вход в полноэкранный режим Выход из полноэкранного режима

Как и ожидалось, все типы данных соответствуют тем, которые были указаны при импорте.

Шаг 3.3. Проверка на наличие значений NaN (Null)

sales_data.isna().sum()
Войдите в полноэкранный режим Выйти из полноэкранного режима

В кадре данных sales_data нет значений NaN, поскольку он был очищен в первой части, а новые данные и столбцы, созданные во второй части, были проверены на наличие значений NaN перед экспортом данных в новый файл Excel.

Шаг 4. Основные функции анализа с помощью Pandas

Прежде всего, давайте рассмотрим некоторые основные функции анализа, которые можно выполнять с помощью Pandas. Это лишь небольшой пример того, что можно сделать, поэтому я рекомендую обратиться к документации Pandas, если вам нужно узнать, как выполнить определенную функцию для фрейма данных.

Шаг 4.1. Общее количество заказов

Хотя это не совсем специфическая функция Pandas, она полезна для того, чтобы показать, сколько строк находится в кадре данных sales_data.

print(f"Total Number of Orders: {len(sales_data)}")
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 4.2. Показать заказы с суммой более 50 фунтов стерлингов

Теперь давайте рассмотрим, как сузить некоторые данные в рамке данных sales_data. Для начала давайте посмотрим первые пять заказов, которые имеют значение больше (>) 50 GBP в столбце order_total_inc_vat_converted_gbp.

sales_data[sales_data["order_total_inc_vat_converted_gbp"] > 50].head(n = 5)
Войти в полноэкранный режим Выход из полноэкранного режима

Вы можете заменить > на < (меньше чем), если вам нужно найти значения меньше 50 фунтов стерлингов.

Шаг 4.3. Показать порядок наибольшего значения

Далее воспользуемся функцией max(), чтобы найти заказ в датафрейме sales_data с наибольшим значением в колонке order_total_inc_vat_converted_gbp.

sales_data[sales_data["order_total_inc_vat_converted_gbp"] == sales_data["order_total_inc_vat_converted_gbp"].max()]
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 4.4. Показать заказ с наименьшим значением

Наконец, воспользуемся функцией min(), чтобы найти заказ в датафрейме sales_data с наименьшим значением в колонке order_total_inc_vat_converted_gbp.

sales_data[sales_data["order_total_inc_vat_converted_gbp"] == sales_data["order_total_inc_vat_converted_gbp"].min()]
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 5. Группировка данных по критериям

В этом разделе я покажу, как использовать функцию groupby, а также несколько других, которые можно использовать вместе с ней.

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

Шаг 5.1. Общее количество заказов по валюте

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

sales_data.groupby(["order_currency"]).size()
Войти в полноэкранный режим Выйти из полноэкранного режима

В приведенном выше примере groupby сгруппирует записи, найденные в колонке order_currency (GBP и EUR в данном случае), а size подсчитает каждую найденную запись.

Теперь давайте сделаем вывод более презентабельным, поместив его во фрейм с помощью функции to_frame.

Пока мы это делаем, давайте отсортируем ордера по валюте с наименьшим количеством ордеров, используя функцию sort_values.

sales_data.groupby(["order_currency"])
          .size()
          .to_frame("total_number_of_orders")
          .sort_values("total_number_of_orders", 
                       ascending = True)  
Вход в полноэкранный режим Выход из полноэкранного режима

Так выглядит лучше!

Шаг 5.2. Общее количество заказов по полу

Используя тот же метод, что и выше, давайте посмотрим на общее количество заказов по полу покупателей.

sales_data.groupby(["customer_gender"])
          .size()
          .to_frame("no_of_orders")
          .sort_values("no_of_orders", 
                       ascending = False)
Войдите в полноэкранный режим Выйти из полноэкранного режима

Шаг 5.3. Общая стоимость заказов по полу

Теперь, когда известно общее количество заказов по полу, давайте посмотрим, какова общая стоимость заказов для каждого пола. В этом шаге будет использована функция agg для выполнения агрегирования заказов, передав словарь столбцов и функцию для использования. В данном примере это будет только столбец order_total_inc_vat_converted_gbp.

В рамках этого NumPy будет использоваться для выполнения суммирования (np.sum) по заказам, найденным для каждого пола.

Наконец, функция round используется для округления результатов до двух десятичных знаков.

sales_data.groupby(["customer_gender"])
          .agg({"order_total_inc_vat_converted_gbp": np.sum})
          .sort_values(["order_total_inc_vat_converted_gbp"], 
                       ascending = False)
          .round(2)
Вход в полноэкранный режим Выход из полноэкранного режима

Кстати, с помощью функции agg можно передавать несколько столбцов и функций, таких как сумма, среднее и медиана. Пример того, как это сделать, приведен в шаге 6.2.

Шаг 6. Использование среднего значения

В этом разделе функция mean, а именно функция np.mean (NumPy), будет использоваться для агрегирования данных в датафрейме sales_data.

Что такое среднее значение?

Среднее значение — это общее количество чисел в данном столбце, разделенное на количество чисел, будь то общее количество в столбце или количество, которое было отфильтровано.

Шаг 6.1. Получение среднего значения всех заказов

Сначала запустим mean для столбца order_total_inc_vat_converted_gbp.

print(f"Mean of all orders (Converted to GBP): £{np.mean(sales_data['order_total_inc_vat_converted_gbp']):.2f}")
Войдите в полноэкранный режим Выход из полноэкранного режима

Небольшое замечание: :.2f покажет только два знака после запятой.

Шаг 6.2. Получение среднего количества заказов по странам

Далее воспользуемся agg для получения среднего значения столбцов order_total_inc_vat_local_currency и order_total_inc_vat_converted_gbp и воспользуемся groupby для группировки результатов по странам и используемой валюте.

sales_data.groupby(["customer_country", "order_currency"])
          .agg({"order_total_inc_vat_local_currency": np.mean,
                "order_total_inc_vat_converted_gbp":  np.mean},)
          .sort_values(["order_total_inc_vat_converted_gbp"], 
                       ascending = False)
          .round(2)
Вход в полноэкранный режим Выход из полноэкранного режима

Как показано выше, результаты группируются по странам и валютам.

Шаг 6.3. Получение среднего количества заказов по стране, городу и полу

Продолжая предыдущий пример, давайте пойдем немного дальше. На этот раз для группировки будем использовать три столбца, а среднее значение получим только по столбцу order_total_inc_vat_converted_gbp.

sales_data.groupby(["customer_country", "customer_city", "customer_gender"])
          .agg({"order_total_inc_vat_converted_gbp": np.mean})
          .sort_values(["order_total_inc_vat_converted_gbp"], 
                       ascending = False)
          .round(2)
Вход в полноэкранный режим Выход из полноэкранного режима

На этот раз результаты сгруппированы по странам, городам и полу. Это позволит глубже изучить покупателей по каждому из них и может быть расширено, чтобы увидеть, что они покупают.

Шаг 7. Использование медианы

Теперь, когда мы рассмотрели среднее значение, давайте рассмотрим использование медианы. Процесс использования медианы практически такой же, как и среднего, просто замените mean на median.

Что такое медиана?

Медиана — это среднее число, которое находится путем расположения всех данных в столбце по порядку (от наименьшего к наибольшему) и нахождения среднего числа. Если есть два средних числа (обычно четное количество записей), то для получения медианы будет вычислено среднее значение этих двух чисел.

Приведенные ниже два примера аналогичны примерам, использованным в шаге 6, только вместо np.median (NumPy median) используется np.mean (NumPy mean).

Шаг 7.1. Получение медианы заказов по странам

sales_data.groupby(["customer_country"])
          .agg({"order_total_inc_vat_converted_gbp": np.median},)
          .sort_values(["order_total_inc_vat_converted_gbp"], 
                       ascending = False)
          .round(2)
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Шаг 7.2. Получение медианы заказов по стране, городу и полу

sales_data.groupby(["customer_country", "customer_city", "customer_gender"])
          .agg({"order_total_inc_vat_converted_gbp": np.median})
          .sort_values(["order_total_inc_vat_converted_gbp"], 
                       ascending = False)
          .round(2)
Войдите в полноэкранный режим Выйти из полноэкранного режима

результат, полученный выше

Шаг 8. Работа с датами

Этот заключительный раздел посвящен использованию дат с рамками данных Pandas. Использовать даты можно разными способами, но я рассмотрю только несколько. Не стесняйтесь оставлять комментарии о том, как вы обычно используете даты с рамками данных Pandas.

Шаг 8.1. Воссоздайте индекс для фрейма данных с датами для индекса

Сначала мы создадим индекс для датафрейма sales_data, используя значения, хранящиеся в столбце order_date. Это позволит рассматривать кадр данных sales_data как кадр данных на основе временного ряда, который работает быстрее при использовании дат и/или времени.

sales_data.set_index([sales_data["order_date"]], 
                     inplace = True)

sales_data.index.rename("date", 
                        inplace = True)

sales_data.head(n = 2)
Вход в полноэкранный режим Выход из полноэкранного режима

Индекс (первый столбец слева) теперь показывает ту же дату в строке, что и order_date.

Шаг 8.2. Вычислите итоговые суммы заказов за день в определенном диапазоне

Теперь, когда дата-фрейм sales_data проиндексирован датами, давайте воспользуемся этим. Для этого используется функция loc. Эта функция найдет в индексе записи, которые подпадают под заданные критерии.

В приведенном ниже примере loc будет искать в индексе значения, которые соответствуют периоду между первым апреля 2020 года и десятым апреля 2020 года.

После этого он сгруппирует найденные заказы по столбцу order_date и выполнит суммирование по столбцу order_total_inc_vat_converted_gbp для всех заказов, размещенных в каждый день. В результате будет показан каждый день и общая сумма за этот день.

start_date = "2020-04-01"
end_date   = "2020-04-10"

sales_data.loc[start_date : end_date]
          .groupby(["order_date"])
          .agg({"order_total_inc_vat_converted_gbp": np.sum})
          .sort_values("order_date", 
                       ascending = True)
          .round(2)
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 8.3. Показать общее количество заказов и среднее значение для каждого года

Далее рассмотрим получение общего и среднего значения для каждого года, которое находится в индексе данных sales_data. Для этого индекс будет повторно сэмплирован с помощью функции resample, которая группирует индекс и записи датафрейма sales_data по году ("Y").

Это не повлияет на кадр данных sales_data, так как он не будет переназначен с пересэмплированными данными.

Кроме того, функция agg будет выполнена несколько иначе. На этот раз мы будем использовать метод, который позволит нам указать имя столбца в выводе для каждого указанного столбца. Например, вместо order_total_inc_vat_converted_gbp имя столбца в выводе будет year_total_gbp.

sales_data.resample("Y")
          .agg(year_total_gbp = ("order_total_inc_vat_converted_gbp", np.sum),
               year_mean_gbp  = ("order_total_inc_vat_converted_gbp", np.mean))
          .round(2)
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 8.4. Показать общие значения заказов и среднее значение для одного года

Теперь, когда вы увидели, как это делается для каждого года, давайте сделаем это снова, но покажем результаты только для одного года.

Для этого сначала нужно передать функцию loc, которая будет использовать индекс для фильтрации по указанному году. В данном случае годом будет 2020, но есть данные и для 2021, если вы хотите попробовать.

year_to_use = 2020

sales_data.loc[sales_data.index.year == year]
          .resample("Y")
          .agg(year_total_gbp = ("order_total_inc_vat_converted_gbp", np.sum),
               year_mean_gbp  = ("order_total_inc_vat_converted_gbp", np.mean))
Вход в полноэкранный режим Выйти из полноэкранного режима

Шаг 8.5. Показать общее количество заказов и среднее значение по месяцам для каждого года

Наконец, давайте получим общую сумму заказов и среднее значение для каждого месяца ("M"), который находится в индексе датафрейма sales_data.

sales_data.resample("M")
          .agg(month_total_gbp = ("order_total_inc_vat_converted_gbp", np.sum),
               month_mean_gbp  = ("order_total_inc_vat_converted_gbp", np.mean))
          .round(2)
Вход в полноэкранный режим Выход из полноэкранного режима

Если изменить resample("M") на resample("Q"), будут показаны результаты за каждый квартал года.

Ресурсы

Файлы GitHub для части 3

Оцените статью
devanswers.ru
Добавить комментарий