eland/docs/sphinx/examples/online_retail_analysis.ipynb
Liam Thompson 0a6e3db157
[DOCS] Make online retail notebook runnable in Colab (#641)
* Make online retail notebook runnable in Colab

* Fix broken query
2024-01-18 15:55:20 +04:00

2307 lines
136 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"source": [
"# Online retail analysis using Eland\n",
"\n",
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/elastic/eland/blob/main/docs/sphinx/examples/online_retail_analysis.ipynb)\n",
"\n",
"Learn how to analyze some online retail data using Eland."
],
"metadata": {
"id": "2IM_dmhFeRhR"
}
},
{
"cell_type": "markdown",
"source": [
"## Install and import packages"
],
"metadata": {
"id": "xx09MAYFe3Ep"
}
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:06.764412Z",
"iopub.status.busy": "2021-12-15T20:25:06.755567Z",
"iopub.status.idle": "2021-12-15T20:25:07.316950Z",
"shell.execute_reply": "2021-12-15T20:25:07.316561Z"
},
"id": "Z7MEVJy9W_sd",
"outputId": "91b215ff-9f4f-4b1f-d204-f24bcc38b3f6",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Collecting eland\n",
" Downloading eland-8.11.1-py3-none-any.whl (157 kB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m157.9/157.9 kB\u001b[0m \u001b[31m3.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hCollecting elasticsearch<9,>=8.3 (from eland)\n",
" Downloading elasticsearch-8.11.1-py3-none-any.whl (412 kB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m412.8/412.8 kB\u001b[0m \u001b[31m8.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hRequirement already satisfied: pandas<2,>=1.5 in /usr/local/lib/python3.10/dist-packages (from eland) (1.5.3)\n",
"Requirement already satisfied: matplotlib>=3.6 in /usr/local/lib/python3.10/dist-packages (from eland) (3.7.1)\n",
"Requirement already satisfied: numpy<2,>=1.2.0 in /usr/local/lib/python3.10/dist-packages (from eland) (1.23.5)\n",
"Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from eland) (23.2)\n",
"Collecting elastic-transport<9,>=8 (from elasticsearch<9,>=8.3->eland)\n",
" Downloading elastic_transport-8.11.0-py3-none-any.whl (59 kB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m59.8/59.8 kB\u001b[0m \u001b[31m7.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hRequirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.6->eland) (1.2.0)\n",
"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.6->eland) (0.12.1)\n",
"Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.6->eland) (4.47.0)\n",
"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.6->eland) (1.4.5)\n",
"Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.6->eland) (9.4.0)\n",
"Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.6->eland) (3.1.1)\n",
"Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.6->eland) (2.8.2)\n",
"Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas<2,>=1.5->eland) (2023.3.post1)\n",
"Requirement already satisfied: urllib3<3,>=1.26.2 in /usr/local/lib/python3.10/dist-packages (from elastic-transport<9,>=8->elasticsearch<9,>=8.3->eland) (2.0.7)\n",
"Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from elastic-transport<9,>=8->elasticsearch<9,>=8.3->eland) (2023.11.17)\n",
"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.7->matplotlib>=3.6->eland) (1.16.0)\n",
"Installing collected packages: elastic-transport, elasticsearch, eland\n",
"Successfully installed eland-8.11.1 elastic-transport-8.11.0 elasticsearch-8.11.1\n",
"Requirement already satisfied: elasticsearch in /usr/local/lib/python3.10/dist-packages (8.11.1)\n",
"Requirement already satisfied: elastic-transport<9,>=8 in /usr/local/lib/python3.10/dist-packages (from elasticsearch) (8.11.0)\n",
"Requirement already satisfied: urllib3<3,>=1.26.2 in /usr/local/lib/python3.10/dist-packages (from elastic-transport<9,>=8->elasticsearch) (2.0.7)\n",
"Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from elastic-transport<9,>=8->elasticsearch) (2023.11.17)\n"
]
}
],
"source": [
"!pip install eland\n",
"!pip install elasticsearch\n",
"\n",
"from elasticsearch import Elasticsearch\n",
"import eland as ed\n",
"import getpass\n",
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# Fix console size for consistent test results\n",
"from eland.conftest import *"
]
},
{
"cell_type": "markdown",
"source": [
"## Connect to Elasticsearch\n",
"\n",
"First we need to connect to a running Elasticsearch instance.\n",
"In this example we'll be using Elastic Cloud.\n",
"Sign up for a [free trial](https://cloud.elastic.co/registration).\n",
"\n",
"See [documentation](https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/connecting.html#connect-self-managed-new) if you want to connect to a self-managed cluster."
],
"metadata": {
"id": "SD0Ul-I_Xipy"
}
},
{
"cell_type": "code",
"source": [
"# Connect to an Elastic Cloud instance\n",
"\n",
"ELASTIC_CLOUD_ID = getpass.getpass(\"Cloud ID:\")\n",
"ELASTIC_CLOUD_PASSWORD = getpass.getpass(\"`elastic` user password:\")\n",
"\n",
"es = Elasticsearch(\n",
" cloud_id=ELASTIC_CLOUD_ID,\n",
" basic_auth=(\"elastic\", ELASTIC_CLOUD_PASSWORD)\n",
")\n",
"print(es.info())"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "mNrJvFU1Yagd",
"outputId": "db8829bf-bd59-4d86-8b73-c956d09f373e"
},
"execution_count": 4,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Cloud ID:··········\n",
"`elastic` user password:··········\n",
"{'name': 'instance-0000000001', 'cluster_name': '69662f53fe844e2d81effcbc7f41e867', 'cluster_uuid': 'GHyCC4NpTAC3SyxZkx65Jw', 'version': {'number': '8.12.0-SNAPSHOT', 'build_flavor': 'default', 'build_type': 'docker', 'build_hash': '38ddf39a3efc422a702adc83b1bb2cd6fc2edc5b', 'build_date': '2024-01-03T12:58:40.771552945Z', 'build_snapshot': True, 'lucene_version': '9.9.1', 'minimum_wire_compatibility_version': '7.17.0', 'minimum_index_compatibility_version': '7.0.0'}, 'tagline': 'You Know, for Search'}\n"
]
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uvhOwB3dW_sg"
},
"source": [
"## Download test data\n",
"\n",
"Let's start by downloading our test data."
]
},
{
"cell_type": "code",
"source": [
"import requests\n",
"\n",
"# URL of the raw file on GitHub\n",
"file_url = \"https://github.com/elastic/eland/raw/main/docs/sphinx/examples/data/online-retail.csv.gz\"\n",
"\n",
"# Local path where you want to save the file\n",
"local_filename = \"online-retail.csv.gz\"\n",
"\n",
"# Send a GET request to the file URL\n",
"response = requests.get(file_url, stream=True)\n",
"\n",
"# Open a local file in binary write mode\n",
"with open(local_filename, 'wb') as file:\n",
" for chunk in response.iter_content(chunk_size=128):\n",
" file.write(chunk)\n",
"\n",
"print(f\"File downloaded: {local_filename}\")"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "FTCeS2rFZrYh",
"outputId": "131aeeac-0af5-4746-e639-626b3c80fb69"
},
"execution_count": 5,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"File downloaded: online-retail.csv.gz\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"## Create Eland dataframe\n",
"\n",
"To get started, let's create an `eland.DataFrame` by reading a csv file. This creates and populates the\n",
"`online-retail` index in the local Elasticsearch cluster."
],
"metadata": {
"id": "V-BiYFnvZwTd"
}
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:07.324283Z",
"iopub.status.busy": "2021-12-15T20:25:07.323764Z",
"iopub.status.idle": "2021-12-15T20:25:16.241379Z",
"shell.execute_reply": "2021-12-15T20:25:16.241877Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "3Pq2jtVQW_sh",
"outputId": "e677a2eb-e59d-4403-f19b-7326ec954a6b"
},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"/usr/local/lib/python3.10/dist-packages/eland/etl.py:529: FutureWarning: the 'mangle_dupe_cols' keyword is deprecated and will be removed in a future version. Please take steps to stop the use of 'mangle_dupe_cols'\n",
" reader = pd.read_csv(filepath_or_buffer, **kwargs)\n",
"/usr/local/lib/python3.10/dist-packages/eland/etl.py:529: FutureWarning: The squeeze argument has been deprecated and will be removed in a future version. Append .squeeze(\"columns\") to the call to squeeze.\n",
"\n",
"\n",
" reader = pd.read_csv(filepath_or_buffer, **kwargs)\n"
]
}
],
"source": [
"df = ed.csv_to_eland(\"online-retail.csv.gz\",\n",
" es_client=es,\n",
" es_dest_index='online-retail',\n",
" es_if_exists='replace',\n",
" es_dropna=True,\n",
" es_refresh=True,\n",
" compression='gzip',\n",
" index_col=0)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "RT8kO2rqW_sh"
},
"source": [
"Here we see that the `\"_id\"` field was used to index our data frame."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:16.246737Z",
"iopub.status.busy": "2021-12-15T20:25:16.244084Z",
"iopub.status.idle": "2021-12-15T20:25:16.250080Z",
"shell.execute_reply": "2021-12-15T20:25:16.250410Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 35
},
"id": "x2um6Xd4W_sh",
"outputId": "69a5a3b3-95cb-4851-dec5-f54e55d16235"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"'_id'"
],
"application/vnd.google.colaboratory.intrinsic+json": {
"type": "string"
}
},
"metadata": {},
"execution_count": 7
}
],
"source": [
"df.index.es_index_field"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YHFiR_8MW_si"
},
"source": [
"Next, we can check which field from elasticsearch are available to our eland data frame. `columns` is available as a parameter when instantiating the data frame which allows one to choose only a subset of fields from your index to be included in the data frame. Since we didn't set this parameter, we have access to all fields."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:16.254703Z",
"iopub.status.busy": "2021-12-15T20:25:16.254060Z",
"iopub.status.idle": "2021-12-15T20:25:16.256567Z",
"shell.execute_reply": "2021-12-15T20:25:16.256138Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "h_6_2YphW_si",
"outputId": "1fb83e3b-8827-4f18-db7d-79bb25e7123d"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"Index(['Country', 'CustomerID', 'Description', 'InvoiceDate', 'InvoiceNo', 'Quantity', 'StockCode',\n",
" 'UnitPrice'],\n",
" dtype='object')"
]
},
"metadata": {},
"execution_count": 8
}
],
"source": [
"df.columns"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "-LmvXDA3W_si"
},
"source": [
"Now, let's see the data types of our fields. Running `df.dtypes`, we can see that elasticsearch field types are mapped to pandas field types."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:16.261335Z",
"iopub.status.busy": "2021-12-15T20:25:16.260762Z",
"iopub.status.idle": "2021-12-15T20:25:16.263024Z",
"shell.execute_reply": "2021-12-15T20:25:16.263323Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "4KEZ3zsEW_si",
"outputId": "090674df-7f4d-41bd-b4bf-3ee476945775"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"Country object\n",
"CustomerID float64\n",
"Description object\n",
"InvoiceDate object\n",
"InvoiceNo object\n",
"Quantity int64\n",
"StockCode object\n",
"UnitPrice float64\n",
"dtype: object"
]
},
"metadata": {},
"execution_count": 9
}
],
"source": [
"df.dtypes"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4Levcmf0W_si"
},
"source": [
"We also offer a `.es_info()` data frame method that shows all info about the underlying index. It also contains information about operations being passed from data frame methods to elasticsearch. More on this later."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:16.266245Z",
"iopub.status.busy": "2021-12-15T20:25:16.265860Z",
"iopub.status.idle": "2021-12-15T20:25:16.271135Z",
"shell.execute_reply": "2021-12-15T20:25:16.270816Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "RhxvDBAiW_si",
"outputId": "db60167f-d973-41d9-bd42-438855cef1a4"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"es_index_pattern: online-retail\n",
"Index:\n",
" es_index_field: _id\n",
" is_source_field: False\n",
"Mappings:\n",
" capabilities:\n",
" es_field_name is_source es_dtype es_date_format pd_dtype is_searchable is_aggregatable is_scripted aggregatable_es_field_name\n",
"Country Country True keyword None object True True False Country\n",
"CustomerID CustomerID True double None float64 True True False CustomerID\n",
"Description Description True keyword None object True True False Description\n",
"InvoiceDate InvoiceDate True keyword None object True True False InvoiceDate\n",
"InvoiceNo InvoiceNo True keyword None object True True False InvoiceNo\n",
"Quantity Quantity True long None int64 True True False Quantity\n",
"StockCode StockCode True keyword None object True True False StockCode\n",
"UnitPrice UnitPrice True double None float64 True True False UnitPrice\n",
"Operations:\n",
" tasks: []\n",
" size: None\n",
" sort_params: None\n",
" _source: ['Country', 'CustomerID', 'Description', 'InvoiceDate', 'InvoiceNo', 'Quantity', 'StockCode', 'UnitPrice']\n",
" body: {}\n",
" post_processing: []\n",
"\n"
]
}
],
"source": [
"print(df.es_info())"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Zlp7YIrPW_sj"
},
"source": [
"## Selecting and Indexing Data\n",
"\n",
"Now that we understand how to create a data frame and get access to it's underlying attributes, let's see how we can select subsets of our data."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6dvAlxBTW_sj"
},
"source": [
"### head and tail\n",
"\n",
"much like pandas, eland data frames offer `.head(n)` and `.tail(n)` methods that return the first and last n rows, respectively."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:16.274779Z",
"iopub.status.busy": "2021-12-15T20:25:16.274393Z",
"iopub.status.idle": "2021-12-15T20:25:17.555325Z",
"shell.execute_reply": "2021-12-15T20:25:17.555642Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 140
},
"id": "WaV6ZJ7CW_sj",
"outputId": "203a8b15-5a08-4808-a675-8a98d1174c1e"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Country CustomerID ... StockCode UnitPrice\n",
"0 United Kingdom 17850.0 ... 85123A 2.55\n",
"1 United Kingdom 17850.0 ... 71053 3.39\n",
"\n",
"[2 rows x 8 columns]"
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Country</th>\n",
" <th>CustomerID</th>\n",
" <th>...</th>\n",
" <th>StockCode</th>\n",
" <th>UnitPrice</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>United Kingdom</td>\n",
" <td>17850.0</td>\n",
" <td>...</td>\n",
" <td>85123A</td>\n",
" <td>2.55</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>United Kingdom</td>\n",
" <td>17850.0</td>\n",
" <td>...</td>\n",
" <td>71053</td>\n",
" <td>3.39</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
"<p>2 rows × 8 columns</p>"
]
},
"metadata": {},
"execution_count": 11
}
],
"source": [
"df.head(2)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:17.559534Z",
"iopub.status.busy": "2021-12-15T20:25:17.559123Z",
"iopub.status.idle": "2021-12-15T20:25:17.637500Z",
"shell.execute_reply": "2021-12-15T20:25:17.637125Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "XpwHbrGwW_sj",
"outputId": "130ba338-abcf-4fe4-cce3-a1840f0fe46b"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"es_index_pattern: online-retail\n",
"Index:\n",
" es_index_field: _id\n",
" is_source_field: False\n",
"Mappings:\n",
" capabilities:\n",
" es_field_name is_source es_dtype es_date_format pd_dtype is_searchable is_aggregatable is_scripted aggregatable_es_field_name\n",
"Country Country True keyword None object True True False Country\n",
"CustomerID CustomerID True double None float64 True True False CustomerID\n",
"Description Description True keyword None object True True False Description\n",
"InvoiceDate InvoiceDate True keyword None object True True False InvoiceDate\n",
"InvoiceNo InvoiceNo True keyword None object True True False InvoiceNo\n",
"Quantity Quantity True long None int64 True True False Quantity\n",
"StockCode StockCode True keyword None object True True False StockCode\n",
"UnitPrice UnitPrice True double None float64 True True False UnitPrice\n",
"Operations:\n",
" tasks: [('tail': ('sort_field': '_doc', 'count': 2)), ('head': ('sort_field': '_doc', 'count': 2)), ('tail': ('sort_field': '_doc', 'count': 2))]\n",
" size: 2\n",
" sort_params: {'_doc': 'desc'}\n",
" _source: ['Country', 'CustomerID', 'Description', 'InvoiceDate', 'InvoiceNo', 'Quantity', 'StockCode', 'UnitPrice']\n",
" body: {}\n",
" post_processing: [('sort_index'), ('head': ('count': 2)), ('tail': ('count': 2))]\n",
"\n"
]
}
],
"source": [
"print(df.tail(2).head(2).tail(2).es_info())"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:17.640519Z",
"iopub.status.busy": "2021-12-15T20:25:17.640139Z",
"iopub.status.idle": "2021-12-15T20:25:18.647340Z",
"shell.execute_reply": "2021-12-15T20:25:18.646548Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 140
},
"id": "Zf-TFwvXW_sj",
"outputId": "4300d820-843d-448f-879d-586756c2e620"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Country CustomerID ... StockCode UnitPrice\n",
"14998 United Kingdom 17419.0 ... 21773 1.25\n",
"14999 United Kingdom 17419.0 ... 22149 2.10\n",
"\n",
"[2 rows x 8 columns]"
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Country</th>\n",
" <th>CustomerID</th>\n",
" <th>...</th>\n",
" <th>StockCode</th>\n",
" <th>UnitPrice</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>14998</th>\n",
" <td>United Kingdom</td>\n",
" <td>17419.0</td>\n",
" <td>...</td>\n",
" <td>21773</td>\n",
" <td>1.25</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14999</th>\n",
" <td>United Kingdom</td>\n",
" <td>17419.0</td>\n",
" <td>...</td>\n",
" <td>22149</td>\n",
" <td>2.10</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
"<p>2 rows × 8 columns</p>"
]
},
"metadata": {},
"execution_count": 13
}
],
"source": [
"df.tail(2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "AkbC-qckW_sj"
},
"source": [
"### Selecting columns\n",
"\n",
"you can also pass a list of columns to select columns from the data frame in a specified order."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:18.654238Z",
"iopub.status.busy": "2021-12-15T20:25:18.653517Z",
"iopub.status.idle": "2021-12-15T20:25:19.431749Z",
"shell.execute_reply": "2021-12-15T20:25:19.431127Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 233
},
"id": "Tdhy8cQzW_sk",
"outputId": "ab4bcc6b-43ab-45b3-8880-545d52410851"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Country InvoiceDate\n",
"0 United Kingdom 2010-12-01 08:26:00\n",
"1 United Kingdom 2010-12-01 08:26:00\n",
"2 United Kingdom 2010-12-01 08:26:00\n",
"3 United Kingdom 2010-12-01 08:26:00\n",
"4 United Kingdom 2010-12-01 08:26:00\n",
"\n",
"[5 rows x 2 columns]"
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Country</th>\n",
" <th>InvoiceDate</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>United Kingdom</td>\n",
" <td>2010-12-01 08:26:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>United Kingdom</td>\n",
" <td>2010-12-01 08:26:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>United Kingdom</td>\n",
" <td>2010-12-01 08:26:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>United Kingdom</td>\n",
" <td>2010-12-01 08:26:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>United Kingdom</td>\n",
" <td>2010-12-01 08:26:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
"<p>5 rows × 2 columns</p>"
]
},
"metadata": {},
"execution_count": 14
}
],
"source": [
"df[['Country', 'InvoiceDate']].head(5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CYV4WfSHW_sk"
},
"source": [
"### Boolean Indexing\n",
"\n",
"we also allow you to filter the data frame using boolean indexing. Under the hood, a boolean index maps to a `terms` query that is then passed to elasticsearch to filter the index."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:19.440640Z",
"iopub.status.busy": "2021-12-15T20:25:19.439831Z",
"iopub.status.idle": "2021-12-15T20:25:20.066747Z",
"shell.execute_reply": "2021-12-15T20:25:20.067477Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 250
},
"id": "p2SPKSOEW_sk",
"outputId": "288a036f-fda0-4d22-9fb4-15ba2cb551b3"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"{'term': {'Country': 'Germany'}}\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Country CustomerID ... StockCode UnitPrice\n",
"1109 Germany 12662.0 ... 22809 2.95\n",
"1110 Germany 12662.0 ... 84347 2.55\n",
"1111 Germany 12662.0 ... 84945 0.85\n",
"1112 Germany 12662.0 ... 22242 1.65\n",
"1113 Germany 12662.0 ... 22244 1.95\n",
"\n",
"[5 rows x 8 columns]"
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Country</th>\n",
" <th>CustomerID</th>\n",
" <th>...</th>\n",
" <th>StockCode</th>\n",
" <th>UnitPrice</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>1109</th>\n",
" <td>Germany</td>\n",
" <td>12662.0</td>\n",
" <td>...</td>\n",
" <td>22809</td>\n",
" <td>2.95</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1110</th>\n",
" <td>Germany</td>\n",
" <td>12662.0</td>\n",
" <td>...</td>\n",
" <td>84347</td>\n",
" <td>2.55</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1111</th>\n",
" <td>Germany</td>\n",
" <td>12662.0</td>\n",
" <td>...</td>\n",
" <td>84945</td>\n",
" <td>0.85</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1112</th>\n",
" <td>Germany</td>\n",
" <td>12662.0</td>\n",
" <td>...</td>\n",
" <td>22242</td>\n",
" <td>1.65</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1113</th>\n",
" <td>Germany</td>\n",
" <td>12662.0</td>\n",
" <td>...</td>\n",
" <td>22244</td>\n",
" <td>1.95</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
"<p>5 rows × 8 columns</p>"
]
},
"metadata": {},
"execution_count": 15
}
],
"source": [
"# the construction of a boolean vector maps directly to an elasticsearch query\n",
"print(df['Country']=='Germany')\n",
"df[(df['Country']=='Germany')].head(5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xV2bkyC3W_sk"
},
"source": [
"we can also filter the data frame using a list of values."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:20.077022Z",
"iopub.status.busy": "2021-12-15T20:25:20.076412Z",
"iopub.status.idle": "2021-12-15T20:25:21.233013Z",
"shell.execute_reply": "2021-12-15T20:25:21.234073Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 250
},
"id": "atifgs9hW_sk",
"outputId": "26468789-6032-428c-f64a-ce36c5a5f426"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"{'terms': {'Country': ['Germany', 'United States']}}\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Country CustomerID ... StockCode UnitPrice\n",
"0 United Kingdom 17850.0 ... 85123A 2.55\n",
"1 United Kingdom 17850.0 ... 71053 3.39\n",
"2 United Kingdom 17850.0 ... 84406B 2.75\n",
"3 United Kingdom 17850.0 ... 84029G 3.39\n",
"4 United Kingdom 17850.0 ... 84029E 3.39\n",
"\n",
"[5 rows x 8 columns]"
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Country</th>\n",
" <th>CustomerID</th>\n",
" <th>...</th>\n",
" <th>StockCode</th>\n",
" <th>UnitPrice</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>United Kingdom</td>\n",
" <td>17850.0</td>\n",
" <td>...</td>\n",
" <td>85123A</td>\n",
" <td>2.55</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>United Kingdom</td>\n",
" <td>17850.0</td>\n",
" <td>...</td>\n",
" <td>71053</td>\n",
" <td>3.39</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>United Kingdom</td>\n",
" <td>17850.0</td>\n",
" <td>...</td>\n",
" <td>84406B</td>\n",
" <td>2.75</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>United Kingdom</td>\n",
" <td>17850.0</td>\n",
" <td>...</td>\n",
" <td>84029G</td>\n",
" <td>3.39</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>United Kingdom</td>\n",
" <td>17850.0</td>\n",
" <td>...</td>\n",
" <td>84029E</td>\n",
" <td>3.39</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
"<p>5 rows × 8 columns</p>"
]
},
"metadata": {},
"execution_count": 16
}
],
"source": [
"print(df['Country'].isin(['Germany', 'United States']))\n",
"df[df['Country'].isin(['Germany', 'United Kingdom'])].head(5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "oFwNF24EW_sk"
},
"source": [
"We can also combine boolean vectors to further filter the data frame."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:21.245390Z",
"iopub.status.busy": "2021-12-15T20:25:21.244737Z",
"iopub.status.idle": "2021-12-15T20:25:22.358701Z",
"shell.execute_reply": "2021-12-15T20:25:22.355150Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 78
},
"id": "WK3xl6JQW_sk",
"outputId": "7e7d9cb2-79d8-4f2b-bb95-02a316246fa6"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"Empty DataFrame\n",
"Columns: [Country, CustomerID, Description, InvoiceDate, InvoiceNo, Quantity, StockCode, UnitPrice]\n",
"Index: []\n",
"\n",
"[0 rows x 8 columns]"
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Country</th>\n",
" <th>CustomerID</th>\n",
" <th>...</th>\n",
" <th>StockCode</th>\n",
" <th>UnitPrice</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
"<p>0 rows × 8 columns</p>"
]
},
"metadata": {},
"execution_count": 17
}
],
"source": [
"df[(df['Country']=='Germany') & (df['Quantity']>90)]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "OOZMEOTXW_sk"
},
"source": [
"Using this example, let see how eland translates this boolean filter to an elasticsearch `bool` query."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:22.383610Z",
"iopub.status.busy": "2021-12-15T20:25:22.370577Z",
"iopub.status.idle": "2021-12-15T20:25:22.390275Z",
"shell.execute_reply": "2021-12-15T20:25:22.388963Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "zg5CX5A9W_sl",
"outputId": "929c23f7-be9b-4ea6-c1bc-e934f25e9fb0"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"es_index_pattern: online-retail\n",
"Index:\n",
" es_index_field: _id\n",
" is_source_field: False\n",
"Mappings:\n",
" capabilities:\n",
" es_field_name is_source es_dtype es_date_format pd_dtype is_searchable is_aggregatable is_scripted aggregatable_es_field_name\n",
"Country Country True keyword None object True True False Country\n",
"CustomerID CustomerID True double None float64 True True False CustomerID\n",
"Description Description True keyword None object True True False Description\n",
"InvoiceDate InvoiceDate True keyword None object True True False InvoiceDate\n",
"InvoiceNo InvoiceNo True keyword None object True True False InvoiceNo\n",
"Quantity Quantity True long None int64 True True False Quantity\n",
"StockCode StockCode True keyword None object True True False StockCode\n",
"UnitPrice UnitPrice True double None float64 True True False UnitPrice\n",
"Operations:\n",
" tasks: [('boolean_filter': ('boolean_filter': {'bool': {'must': [{'term': {'Country': 'Germany'}}, {'range': {'Quantity': {'gt': 90}}}]}}))]\n",
" size: None\n",
" sort_params: None\n",
" _source: ['Country', 'CustomerID', 'Description', 'InvoiceDate', 'InvoiceNo', 'Quantity', 'StockCode', 'UnitPrice']\n",
" body: {'query': {'bool': {'must': [{'term': {'Country': 'Germany'}}, {'range': {'Quantity': {'gt': 90}}}]}}}\n",
" post_processing: []\n",
"\n"
]
}
],
"source": [
"print(df[(df['Country']=='Germany') & (df['Quantity']>90)].es_info())"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QRTjR8d3W_sl"
},
"source": [
"## Aggregation and Descriptive Statistics\n",
"\n",
"Let's begin to ask some questions of our data and use eland to get the answers."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Pc3OGsQ5W_sl"
},
"source": [
"**How many different countries are there?**"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:22.398231Z",
"iopub.status.busy": "2021-12-15T20:25:22.397459Z",
"iopub.status.idle": "2021-12-15T20:25:22.482238Z",
"shell.execute_reply": "2021-12-15T20:25:22.481338Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "9p8JrleuW_sl",
"outputId": "9323b109-a59a-4b7c-f6c4-14996666591d"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"16"
]
},
"metadata": {},
"execution_count": 19
}
],
"source": [
"df['Country'].nunique()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9w_Ge7ESW_sl"
},
"source": [
"**What is the total sum of products ordered?**"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:22.492668Z",
"iopub.status.busy": "2021-12-15T20:25:22.491590Z",
"iopub.status.idle": "2021-12-15T20:25:22.580015Z",
"shell.execute_reply": "2021-12-15T20:25:22.578300Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "MFu01N3LW_sl",
"outputId": "0e10430a-2a2d-4f4c-be41-01f0bcb9afde"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"111960"
]
},
"metadata": {},
"execution_count": 20
}
],
"source": [
"df['Quantity'].sum()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "-Nwc-ybwW_sl"
},
"source": [
"**Show me the sum, mean, min, and max of the qunatity and unit_price fields**"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:22.601432Z",
"iopub.status.busy": "2021-12-15T20:25:22.600117Z",
"iopub.status.idle": "2021-12-15T20:25:22.702450Z",
"shell.execute_reply": "2021-12-15T20:25:22.701499Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 173
},
"id": "QhqUeIQbW_sl",
"outputId": "aeec1b5e-bee4-4cf5-e338-def0d82b0451"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Quantity UnitPrice\n",
"sum 111960.000 61548.490000\n",
"mean 7.464 4.103233\n",
"max 2880.000 950.990000\n",
"min -9360.000 0.000000"
],
"text/html": [
"\n",
" <div id=\"df-cbfeceb1-2fd7-4a44-acdf-2b6c13dbb9c2\" class=\"colab-df-container\">\n",
" <div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Quantity</th>\n",
" <th>UnitPrice</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>sum</th>\n",
" <td>111960.000</td>\n",
" <td>61548.490000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>7.464</td>\n",
" <td>4.103233</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>2880.000</td>\n",
" <td>950.990000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>-9360.000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
" <div class=\"colab-df-buttons\">\n",
"\n",
" <div class=\"colab-df-container\">\n",
" <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-cbfeceb1-2fd7-4a44-acdf-2b6c13dbb9c2')\"\n",
" title=\"Convert this dataframe to an interactive table.\"\n",
" style=\"display:none;\">\n",
"\n",
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
" <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
" </svg>\n",
" </button>\n",
"\n",
" <style>\n",
" .colab-df-container {\n",
" display:flex;\n",
" gap: 12px;\n",
" }\n",
"\n",
" .colab-df-convert {\n",
" background-color: #E8F0FE;\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: #1967D2;\n",
" height: 32px;\n",
" padding: 0 0 0 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-convert:hover {\n",
" background-color: #E2EBFA;\n",
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: #174EA6;\n",
" }\n",
"\n",
" .colab-df-buttons div {\n",
" margin-bottom: 4px;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert {\n",
" background-color: #3B4455;\n",
" fill: #D2E3FC;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert:hover {\n",
" background-color: #434B5C;\n",
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
" fill: #FFFFFF;\n",
" }\n",
" </style>\n",
"\n",
" <script>\n",
" const buttonEl =\n",
" document.querySelector('#df-cbfeceb1-2fd7-4a44-acdf-2b6c13dbb9c2 button.colab-df-convert');\n",
" buttonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
"\n",
" async function convertToInteractive(key) {\n",
" const element = document.querySelector('#df-cbfeceb1-2fd7-4a44-acdf-2b6c13dbb9c2');\n",
" const dataTable =\n",
" await google.colab.kernel.invokeFunction('convertToInteractive',\n",
" [key], {});\n",
" if (!dataTable) return;\n",
"\n",
" const docLinkHtml = 'Like what you see? Visit the ' +\n",
" '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
" + ' to learn more about interactive tables.';\n",
" element.innerHTML = '';\n",
" dataTable['output_type'] = 'display_data';\n",
" await google.colab.output.renderOutput(dataTable, element);\n",
" const docLink = document.createElement('div');\n",
" docLink.innerHTML = docLinkHtml;\n",
" element.appendChild(docLink);\n",
" }\n",
" </script>\n",
" </div>\n",
"\n",
"\n",
"<div id=\"df-a515a67f-153d-431f-a346-9ad3f849d5b9\">\n",
" <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-a515a67f-153d-431f-a346-9ad3f849d5b9')\"\n",
" title=\"Suggest charts\"\n",
" style=\"display:none;\">\n",
"\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
" width=\"24px\">\n",
" <g>\n",
" <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
" </g>\n",
"</svg>\n",
" </button>\n",
"\n",
"<style>\n",
" .colab-df-quickchart {\n",
" --bg-color: #E8F0FE;\n",
" --fill-color: #1967D2;\n",
" --hover-bg-color: #E2EBFA;\n",
" --hover-fill-color: #174EA6;\n",
" --disabled-fill-color: #AAA;\n",
" --disabled-bg-color: #DDD;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-quickchart {\n",
" --bg-color: #3B4455;\n",
" --fill-color: #D2E3FC;\n",
" --hover-bg-color: #434B5C;\n",
" --hover-fill-color: #FFFFFF;\n",
" --disabled-bg-color: #3B4455;\n",
" --disabled-fill-color: #666;\n",
" }\n",
"\n",
" .colab-df-quickchart {\n",
" background-color: var(--bg-color);\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: var(--fill-color);\n",
" height: 32px;\n",
" padding: 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-quickchart:hover {\n",
" background-color: var(--hover-bg-color);\n",
" box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: var(--button-hover-fill-color);\n",
" }\n",
"\n",
" .colab-df-quickchart-complete:disabled,\n",
" .colab-df-quickchart-complete:disabled:hover {\n",
" background-color: var(--disabled-bg-color);\n",
" fill: var(--disabled-fill-color);\n",
" box-shadow: none;\n",
" }\n",
"\n",
" .colab-df-spinner {\n",
" border: 2px solid var(--fill-color);\n",
" border-color: transparent;\n",
" border-bottom-color: var(--fill-color);\n",
" animation:\n",
" spin 1s steps(1) infinite;\n",
" }\n",
"\n",
" @keyframes spin {\n",
" 0% {\n",
" border-color: transparent;\n",
" border-bottom-color: var(--fill-color);\n",
" border-left-color: var(--fill-color);\n",
" }\n",
" 20% {\n",
" border-color: transparent;\n",
" border-left-color: var(--fill-color);\n",
" border-top-color: var(--fill-color);\n",
" }\n",
" 30% {\n",
" border-color: transparent;\n",
" border-left-color: var(--fill-color);\n",
" border-top-color: var(--fill-color);\n",
" border-right-color: var(--fill-color);\n",
" }\n",
" 40% {\n",
" border-color: transparent;\n",
" border-right-color: var(--fill-color);\n",
" border-top-color: var(--fill-color);\n",
" }\n",
" 60% {\n",
" border-color: transparent;\n",
" border-right-color: var(--fill-color);\n",
" }\n",
" 80% {\n",
" border-color: transparent;\n",
" border-right-color: var(--fill-color);\n",
" border-bottom-color: var(--fill-color);\n",
" }\n",
" 90% {\n",
" border-color: transparent;\n",
" border-bottom-color: var(--fill-color);\n",
" }\n",
" }\n",
"</style>\n",
"\n",
" <script>\n",
" async function quickchart(key) {\n",
" const quickchartButtonEl =\n",
" document.querySelector('#' + key + ' button');\n",
" quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n",
" quickchartButtonEl.classList.add('colab-df-spinner');\n",
" try {\n",
" const charts = await google.colab.kernel.invokeFunction(\n",
" 'suggestCharts', [key], {});\n",
" } catch (error) {\n",
" console.error('Error during call to suggestCharts:', error);\n",
" }\n",
" quickchartButtonEl.classList.remove('colab-df-spinner');\n",
" quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
" }\n",
" (() => {\n",
" let quickchartButtonEl =\n",
" document.querySelector('#df-a515a67f-153d-431f-a346-9ad3f849d5b9 button');\n",
" quickchartButtonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
" })();\n",
" </script>\n",
"</div>\n",
" </div>\n",
" </div>\n"
]
},
"metadata": {},
"execution_count": 21
}
],
"source": [
"df[['Quantity','UnitPrice']].agg(['sum', 'mean', 'max', 'min'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CklumXmiW_sm"
},
"source": [
"**Give me descriptive statistics for the entire data frame**"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:22.712002Z",
"iopub.status.busy": "2021-12-15T20:25:22.711114Z",
"iopub.status.idle": "2021-12-15T20:25:22.982698Z",
"shell.execute_reply": "2021-12-15T20:25:22.981770Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 297
},
"id": "AttDFOcRW_sm",
"outputId": "a515c9f5-5b04-4943-9c72-8da357fa29ae"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" CustomerID Quantity UnitPrice\n",
"count 10729.000000 15000.000000 15000.000000\n",
"mean 15590.776680 7.464000 4.103233\n",
"std 1764.189592 85.930116 20.106214\n",
"min 12347.000000 -9360.000000 0.000000\n",
"25% 14225.913815 1.000000 1.336010\n",
"50% 15668.124797 2.423796 2.396465\n",
"75% 17195.974646 7.403795 4.282239\n",
"max 18239.000000 2880.000000 950.990000"
],
"text/html": [
"\n",
" <div id=\"df-cfeaff95-e82b-4d7c-bbde-299c17b9493e\" class=\"colab-df-container\">\n",
" <div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>CustomerID</th>\n",
" <th>Quantity</th>\n",
" <th>UnitPrice</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>10729.000000</td>\n",
" <td>15000.000000</td>\n",
" <td>15000.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>15590.776680</td>\n",
" <td>7.464000</td>\n",
" <td>4.103233</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>1764.189592</td>\n",
" <td>85.930116</td>\n",
" <td>20.106214</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>12347.000000</td>\n",
" <td>-9360.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>14225.913815</td>\n",
" <td>1.000000</td>\n",
" <td>1.336010</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>15668.124797</td>\n",
" <td>2.423796</td>\n",
" <td>2.396465</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>17195.974646</td>\n",
" <td>7.403795</td>\n",
" <td>4.282239</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>18239.000000</td>\n",
" <td>2880.000000</td>\n",
" <td>950.990000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
" <div class=\"colab-df-buttons\">\n",
"\n",
" <div class=\"colab-df-container\">\n",
" <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-cfeaff95-e82b-4d7c-bbde-299c17b9493e')\"\n",
" title=\"Convert this dataframe to an interactive table.\"\n",
" style=\"display:none;\">\n",
"\n",
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
" <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
" </svg>\n",
" </button>\n",
"\n",
" <style>\n",
" .colab-df-container {\n",
" display:flex;\n",
" gap: 12px;\n",
" }\n",
"\n",
" .colab-df-convert {\n",
" background-color: #E8F0FE;\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: #1967D2;\n",
" height: 32px;\n",
" padding: 0 0 0 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-convert:hover {\n",
" background-color: #E2EBFA;\n",
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: #174EA6;\n",
" }\n",
"\n",
" .colab-df-buttons div {\n",
" margin-bottom: 4px;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert {\n",
" background-color: #3B4455;\n",
" fill: #D2E3FC;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert:hover {\n",
" background-color: #434B5C;\n",
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
" fill: #FFFFFF;\n",
" }\n",
" </style>\n",
"\n",
" <script>\n",
" const buttonEl =\n",
" document.querySelector('#df-cfeaff95-e82b-4d7c-bbde-299c17b9493e button.colab-df-convert');\n",
" buttonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
"\n",
" async function convertToInteractive(key) {\n",
" const element = document.querySelector('#df-cfeaff95-e82b-4d7c-bbde-299c17b9493e');\n",
" const dataTable =\n",
" await google.colab.kernel.invokeFunction('convertToInteractive',\n",
" [key], {});\n",
" if (!dataTable) return;\n",
"\n",
" const docLinkHtml = 'Like what you see? Visit the ' +\n",
" '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
" + ' to learn more about interactive tables.';\n",
" element.innerHTML = '';\n",
" dataTable['output_type'] = 'display_data';\n",
" await google.colab.output.renderOutput(dataTable, element);\n",
" const docLink = document.createElement('div');\n",
" docLink.innerHTML = docLinkHtml;\n",
" element.appendChild(docLink);\n",
" }\n",
" </script>\n",
" </div>\n",
"\n",
"\n",
"<div id=\"df-51e65f9a-bb05-4074-a835-06c70a6b5749\">\n",
" <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-51e65f9a-bb05-4074-a835-06c70a6b5749')\"\n",
" title=\"Suggest charts\"\n",
" style=\"display:none;\">\n",
"\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
" width=\"24px\">\n",
" <g>\n",
" <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
" </g>\n",
"</svg>\n",
" </button>\n",
"\n",
"<style>\n",
" .colab-df-quickchart {\n",
" --bg-color: #E8F0FE;\n",
" --fill-color: #1967D2;\n",
" --hover-bg-color: #E2EBFA;\n",
" --hover-fill-color: #174EA6;\n",
" --disabled-fill-color: #AAA;\n",
" --disabled-bg-color: #DDD;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-quickchart {\n",
" --bg-color: #3B4455;\n",
" --fill-color: #D2E3FC;\n",
" --hover-bg-color: #434B5C;\n",
" --hover-fill-color: #FFFFFF;\n",
" --disabled-bg-color: #3B4455;\n",
" --disabled-fill-color: #666;\n",
" }\n",
"\n",
" .colab-df-quickchart {\n",
" background-color: var(--bg-color);\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: var(--fill-color);\n",
" height: 32px;\n",
" padding: 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-quickchart:hover {\n",
" background-color: var(--hover-bg-color);\n",
" box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: var(--button-hover-fill-color);\n",
" }\n",
"\n",
" .colab-df-quickchart-complete:disabled,\n",
" .colab-df-quickchart-complete:disabled:hover {\n",
" background-color: var(--disabled-bg-color);\n",
" fill: var(--disabled-fill-color);\n",
" box-shadow: none;\n",
" }\n",
"\n",
" .colab-df-spinner {\n",
" border: 2px solid var(--fill-color);\n",
" border-color: transparent;\n",
" border-bottom-color: var(--fill-color);\n",
" animation:\n",
" spin 1s steps(1) infinite;\n",
" }\n",
"\n",
" @keyframes spin {\n",
" 0% {\n",
" border-color: transparent;\n",
" border-bottom-color: var(--fill-color);\n",
" border-left-color: var(--fill-color);\n",
" }\n",
" 20% {\n",
" border-color: transparent;\n",
" border-left-color: var(--fill-color);\n",
" border-top-color: var(--fill-color);\n",
" }\n",
" 30% {\n",
" border-color: transparent;\n",
" border-left-color: var(--fill-color);\n",
" border-top-color: var(--fill-color);\n",
" border-right-color: var(--fill-color);\n",
" }\n",
" 40% {\n",
" border-color: transparent;\n",
" border-right-color: var(--fill-color);\n",
" border-top-color: var(--fill-color);\n",
" }\n",
" 60% {\n",
" border-color: transparent;\n",
" border-right-color: var(--fill-color);\n",
" }\n",
" 80% {\n",
" border-color: transparent;\n",
" border-right-color: var(--fill-color);\n",
" border-bottom-color: var(--fill-color);\n",
" }\n",
" 90% {\n",
" border-color: transparent;\n",
" border-bottom-color: var(--fill-color);\n",
" }\n",
" }\n",
"</style>\n",
"\n",
" <script>\n",
" async function quickchart(key) {\n",
" const quickchartButtonEl =\n",
" document.querySelector('#' + key + ' button');\n",
" quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n",
" quickchartButtonEl.classList.add('colab-df-spinner');\n",
" try {\n",
" const charts = await google.colab.kernel.invokeFunction(\n",
" 'suggestCharts', [key], {});\n",
" } catch (error) {\n",
" console.error('Error during call to suggestCharts:', error);\n",
" }\n",
" quickchartButtonEl.classList.remove('colab-df-spinner');\n",
" quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
" }\n",
" (() => {\n",
" let quickchartButtonEl =\n",
" document.querySelector('#df-51e65f9a-bb05-4074-a835-06c70a6b5749 button');\n",
" quickchartButtonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
" })();\n",
" </script>\n",
"</div>\n",
" </div>\n",
" </div>\n"
]
},
"metadata": {},
"execution_count": 22
}
],
"source": [
"# NBVAL_IGNORE_OUTPUT\n",
"df.describe()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "LfPjHhpKW_sn"
},
"source": [
"**Show me a histogram of numeric columns**"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:23.000466Z",
"iopub.status.busy": "2021-12-15T20:25:22.999571Z",
"iopub.status.idle": "2021-12-15T20:25:23.576387Z",
"shell.execute_reply": "2021-12-15T20:25:23.576703Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 391
},
"id": "ZJ1VoTG_W_sn",
"outputId": "a32d2fec-17db-428a-d4a2-71a17faa41fa"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1200x400 with 2 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA+8AAAF2CAYAAAAfjKmHAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABXHUlEQVR4nO3dfVhUdf7/8RfgMICKeBMgicrWd70pXU1LZ01XEyGX+lpS37UsyUzTsE35baatud6skZT3d2Q33my4qW2Wd6tMmpqJaCTlTdmdZrsGbilOSsII8/uji7NOqHkUmAM8H9fFdXXOeZ8z78+743DenDOf8fN4PB4BAAAAAADL8vd1AgAAAAAA4NJo3gEAAAAAsDiadwAAAAAALI7mHQAAAAAAi6N5BwAAAADA4mjeAQAAAACwOJp3AAAAAAAsjuYdAAAAAACLo3kHAAAAAMDiaN4BXJWePXuqZ8+evk4DAACY8NBDD6lly5ZV9npcLwBXj+Yd8LEDBw7ogQce0LXXXiu73a6oqCg98MADOnjwoK9TMxw8eFATJ07UkSNHfjH22LFjmjhxonJzcys9LwAAarqJEyfKz89P33333QW333jjjRXSFBcWFmrixInaunXrRXMo+wkJCVHbtm01fvx4uVyuq35tAJenjq8TAGqzN998U/fdd58aNWqkIUOGKCYmRkeOHNErr7yiN954QytWrFC/fv18naYOHjyoSZMmqWfPnuX+Sp+Zmem1fOzYMU2aNEktW7ZUhw4dqi5JAABw2V566SWVlpYay4WFhZo0aZIkXfSPAQsXLlS9evV0+vRpZWZmaurUqdqyZYvef/99+fn5XfL1fn69AMA8mnfAR7788ks9+OCD+tWvfqXt27frmmuuMbY98cQT6t69ux544AF9/PHHiomJ8WGmlxYYGOjrFAAAgEk2m830Pvfcc4+aNGkiSRo+fLgSExP15ptvateuXXI4HBfcp7CwUCEhIVwvABWAx+YBH3n++edVWFioRYsWeTXuktSkSRO9+OKLOn36tJ5//nlJF/9sWtmjbOdbvHixbrvtNoWHh8tut6tt27ZauHBhuX1btmypO+64Qzt27NAtt9yioKAg/epXv9KyZcuMmCVLlujee++VJPXq1ct4ZK7ssbrzP8O2detW3XzzzZKkwYMHG7FLlizRX/7yF9lsNv3nP/8pl8ewYcMUFhams2fPXl7xAABAOVu3bpWfn59WrlypqVOnqlmzZgoKClLv3r31xRdfeMWef11x5MgR41pk0qRJxu/viRMnXvL1brvtNknS4cOHJf10TXDjjTcqJydHPXr0UEhIiJ5++mlj28/v6J89e1YTJ07Ur3/9awUFBalp06bq37+/vvzySyOmtLRUs2bN0g033KCgoCBFRETo0Ucf1cmTJ6+0TEC1RfMO+MjatWvVsmVLde/e/YLbe/TooZYtW2rt2rWmj71w4UK1aNFCTz/9tKZPn67o6Gg99thjmj9/frnYL774Qvfcc4/69Omj6dOnq2HDhnrooYd04MABI48//vGPkqSnn35af/vb3/S3v/1Nbdq0KXesNm3aaPLkyZJ+asjLYnv06KEHH3xQ586d04oVK7z2KS4u1htvvKHExEQFBQWZHisAAPD23HPPafXq1frTn/6kcePGadeuXRo4cOBF46+55hrjj/x333238fu7f//+l3ydsia7cePGxrrvv/9effv2VYcOHTRr1iz16tXrgvuWlJTojjvu0KRJk9SpUydNnz5dTzzxhE6dOqX9+/cbcY8++qiefPJJdevWTbNnz9bgwYOVkZGh+Ph4ud3uy64JUBPw2DzgA6dOndKxY8d+8fPs7du315o1a/TDDz+YOv62bdsUHBxsLI8cOVK33367ZsyYoeTkZK/YQ4cOafv27cYfEf7v//5P0dHRWrx4sV544QX96le/Uvfu3TVnzhz16dPnkpPiREREqG/fvpowYYIcDoceeOABr+0Oh0OvvfaaRo4caaxbv369Tp48qQcffNDUGAEAwIWdPXtWubm5xqPqDRs21BNPPKH9+/frxhtvLBdft25d3XPPPRoxYoTat29f7vd3mRMnTkiS8Zn3BQsWKCIiwutGRF5entLT0/Xoo49eMsdly5Zp8+bNmjFjhkaPHm2sHzt2rDwejyRpx44devnll5WRkaH777/fiOnVq5duv/12rVq1yms9UNNx5x3wgbJmvH79+peMK9tutnk/v3E/deqUvvvuO/3ud7/TV199pVOnTnnFtm3b1uuX7jXXXKNWrVrpq6++MvWal2PQoEHKzs72ehwuIyND0dHR+t3vflfhrwcAQG00ePBgr8+Yl/2ev9rf7a1atdI111yjmJgYPfroo7r++uu1fv16hYSEGDF2u12DBw/+xWP94x//UJMmTfT444+X21b2ccBVq1apQYMG6tOnj7777jvjp1OnTqpXr57efffdqxoPUN1w5x3wgcttyn/44Qf5+fkZk8Ncrvfff19/+ctflJWVpcLCQq9tp06dUoMGDYzl5s2bl9u/YcOGlfJZsj/84Q8aNWqUMjIyNGHCBJ06dUrr1q3T6NGjf3GWWgAAcGE//x3689/tDRs2lKSr/t3+j3/8Q6GhobLZbGrWrJmuu+66cjHXXnvtZU1O9+WXX6pVq1aqU+fi7cjnn3+uU6dOKTw8/ILbjx8/fvnJAzUAzTvgAw0aNFBUVJQ+/vjjS8Z9/PHHatasmQIDAy/a3JaUlHgtf/nll+rdu7dat26tGTNmKDo6WoGBgdqwYYNmzpzp9bUwkhQQEHDB45Y9slaRGjZsqDvuuMNo3t944w0VFRVd9PE8AABqu7L5YH788ccLbi8sLCw3Z0xl/W7v0aPHL95QOP/pv6tVWlqq8PBwZWRkXHD7zyf8BWo6mnfAR+688069+OKL2rFjh2699dZy29977z0dOXJEKSkpkn5qfAsKCsrFff31117La9euVVFRkdasWeP1l/erebTMzF3xX4odNGiQ+vXrpz179igjI0MdO3bUDTfccMW5AQBQk7Vo0ULST3PUREdHe20rLCzUN998o7i4uKt+nap+Au66665Tdna23G73Rb+27rrrrtM777yjbt26VegfBYDqis+8Az7ypz/9SSEhIXr00Uf1/fffe207ceKEhg8frtDQUGNyt+uuu06nTp3yulv/7bffavXq1V77lv21/fy/rp86dUqLFy++4lzr1q0rSRf844HZ2L59+6pJkyaaNm2atm3bxl13AAAuoXfv3goMDNTChQvLPT23aNEinTt3Tn379r3q1yn73Prl/K6vCImJifruu+80b968ctvKrmH+7//+TyUlJZoyZUq5mHPnzlVZroBVcOcd8JHrr79ey5Yt03333ad27dppyJAhiomJ0ZEjR/TKK6/o5MmTev311xUTEyNJGjBggJ566indfffd+uMf/6jCwkItXLhQv/71r/Xhhx8ax42Li1NgYKDuvPNOPfroozp9+rReeuklhYeH69tvv72iXDt06KCAgABNmzZNp06dkt1uN75H/ueuu+46hYWFKT09XfXr11fdunXVpUsXYxw2m00DBgzQvHnzFBAQoPvuu++KcgIA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Npuv07E0amXO+fXqOHWLqX33T4yvpKysi/PLnJpWr7InuQAAAHzJVPP+5JNPauzYsRowYIAkqV27dvr666+VmpqqpKQkRUZGSpLy8/PVtGlTY7/8/Hx16NBBkhQZGanjx497HffcuXM6ceKEsX9kZKTy8/O9YsqWy2J+zm63y263l1tvs9mq/cVjTRhDVaFW5thsNhWV+Jnep7bi/DKnptSrJowBAABUf6Zmmy8sLJS/v/cuAQEBKi0tlSTFxMQoMjJSmzdvNra7XC5lZ2fL4XBIkhwOhwoKCpSTk2PEbNmyRaWlperSpYsRs337dq/PGTqdTrVq1eqCj8wDAAAAAFCTmWre77zzTk2dOlXr16/XkSNHtHr1as2YMUN33323JMnPz0+jRo3SX//6V61Zs0b79u3ToEGDFBUVpbvuukuS1KZNG91+++0aOnSodu/erffff18jR47UgAEDFBUVJUm6//77FRgYqCFDhujAgQNasWKFZs+e7fVYPAAAAAAAtYWpx+bnzp2rZ555Ro899piOHz+uqKgoPfroo5owYYIRM2bMGJ05c0bDhg1TQUGBbr31Vm3cuFFBQUFGTEZGhkaOHKnevXvL399fiYmJmjNnjrG9QYMGyszMVHJysjp16qQmTZpowoQJfE0cAAAAAKBWMtW8169fX7NmzdKsWbMuGuPn56fJkydr8uTJF41p1KiRli9ffsnXat++vd577z0z6QEAAAAAUCOZemweAAAAAABUPZp3AAAAAAAsjuYdAAAAAACLo3kHAAAAAMDiaN4BAAAAALA4mncAAAAAACyO5h0AAAAAAIujeQcAAAAAwOJo3gEAAAAAsDiadwAAUClKSkr0zDPPKCYmRsHBwbruuus0ZcoUeTweI8bj8WjChAlq2rSpgoODFRsbq88//9zrOCdOnNDAgQMVGhqqsLAwDRkyRKdPn/aK+fjjj9W9e3cFBQUpOjpaaWlpVTJGAACqCs07AACoFNOmTdPChQs1b948ffLJJ5o2bZrS0tI0d+5cIyYtLU1z5sxRenq6srOzVbduXcXHx+vs2bNGzMCBA3XgwAE5nU6tW7dO27dv17Bhw4ztLpdLcXFxatGihXJycvT8889r4sSJWrRoUZWOFwCAylTH1wkAAICaaefOnerXr58SEhIkSS1bttTf//537d69W9JPd91nzZql8ePHq1+/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mUfNzKNm1sFs8wAAoFJ069ZNhw4d8lr32WefqUWLFpJ+mrwuMjJSmzdvNra7XC5lZ2fL4XBIkhwOhwoKCpSTk2PEbNmyRaWlperSpYsRs337dq/PGjqdTrVq1arcI/MAAFRXNO8AAKBSjB49Wrt27dKzzz6rL774QsuXL9eiRYuUnJwsSfLz89OoUaP017/+VWvWrNG+ffs0aNAgRUVF6a677pL0053622+/XUOHDtXu3bv1/vvva+TIkRowYICioqIkSffff78CAwM1ZMgQHThwQCtWrNDs2bO9Ho0HAKC647F5AABQKW6++WatXr1a48aN0+TJkxUTE6NZs2Zp4MCBRsyYMWN05swZDRs2TAUFBbr11lu1ceNGBQUFGTEZGRkaOXKkevfuLX9/fyUmJmrOnDnG9gYNGigzM1PJycnq1KmTmjRpogkTJvA1cQCAGoXmHQAAVJo77rhDd9xxx0W3+/n5afLkyZo8efJFYxo1aqTly5df8nXat2+v995774rzBADA6nhsHgAAAAAAi6N5BwAAAADA4mjeAQAAAACwOJp3AAAAAAAsjuYdAAAAAACLo3kHAAAAAMDiaN4BAAAAALA4mncAAAAAACyO5h0AAAAAAIsz1bxPnDhRfn5+Xj+tW7c2tp89e1bJyclq3Lix6tWrp8TEROXn53sd4+jRo0pISFBISIjCw8P15JNP6ty5c14xW7du1U033SS73a7rr79eS5YsufIRAgAAAABQzZm+837DDTfo22+/NX527NhhbBs9erTWrl2rVatWadu2bTp27Jj69+9vbC8pKVFCQoKKi4u1c+dOLV26VEuWLNGECROMmMOHDyshIUG9evVSbm6uRo0apUceeUSbNm26yqECAAAAAFA91TG9Q506ioyMLLf+1KlTeuWVV7R8+XLddtttkqTFixerTZs22rVrl7p27arMzEwdPHhQ77zzjiIiItShQwdNmTJFTz31lCZOnKjAwEClp6crJiZG06dPlyS1adNGO3bs0MyZMxUfH3+VwwUAAAAAoPox3bx//vnnioqKUlBQkBwOh1JTU9W8eXPl5OTI7XYrNjbWiG3durWaN2+urKwsde3aVVlZWWrXrp0iIiKMmPj4eI0YMUIHDhxQx44dlZWV5XWMsphRo0ZdMq+ioiIVFRUZyy6XS5LkdrvldrvNDtMSyvKurvlXJWpl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H/GPHj2qESNG6N1331W9evWUlJSk1NRU1anz38uYrVu3KiUlRQcOHFB0dLTGjx+vhx56qCqHCwBApbqi5n3kyJFat26dtm/frmbNmhnrIyMjVVxcrIKCAq+77/n5+YqMjDRidu/e7XW8stnoz4/5+Qz1+fn5Cg0NveBdd0kaN26cUlJSjGWXy6Xo6GjFxcUpNDT0Sobpc263W06nU3369JHNZvN1OpZGrcw5v14dp26p9NfbP7F6z1XB+WVOTatX2ZNcMK9sotubb75Z586d09NPP624uDgdPHhQdevWlfTTRLfr16/XqlWr1KBBA40cOVL9+/fX+++/L+m/E91GRkZq586d+vbbbzVo0CDZbDY9++yzkv470e3w4cOVkZGhzZs365FHHlHTpk2ZKwcAUGOYat49Ho8ef/xxrV69Wlu3blVMTIzX9k6dOslms2nz5s1KTEyUJB06dEhHjx6Vw+GQJDkcDk2dOlXHjx9XeHi4pJ/uzoSGhqpt27ZGzM/v1DmdTuMYF2K322W328utt9ls1f7isSaMoapQK3NsNpuKSvyq5HVqAs4vc2pKvWrCGHyFiW4BAKg4piasS05O1muvvably5erfv36ysvLU15enn788UdJUoMGDTRkyBClpKTo3XffVU5OjgYPHiyHw6GuXbtKkuLi4tS2bVs9+OCD+uijj7Rp0yaNHz9eycnJRvM9fPhwffXVVxozZow+/fRTLViwQCtXrtTo0aMrePgAAKCqMNEtAABXztSd94ULF0qSevbs6bV+8eLFxufKZs6cKX9/fyUmJnp9dq1MQECA1q1bpxEjRsjhcKhu3bpKSkrS5MmTjZiYmBitX79eo0eP1uzZs9WsWTO9/PLL/PUcAIBqykoT3VbWJLdl+9r9K3ci0Jo2iWJNm+SyKlAz86iZedTMvMqulenH5n9JUFCQ5s+fr/nz5180pkWLFr84gVXPnj21d+9eM+kBAACLstJEt5U9ye2UzqVXfYxLqSmTgP5cTZnksipRM/OomXnUzDqueLZ5AACAy2G1iW4ra5Lbsskan/nAX0WllTefSHWfBPTnatokl1WBmplHzcyjZua53W69/fbblXZ8mncAAFAprDrRbWVPcltU6lepk4HW1IvomjLJZVWiZuZRM/OomXXQvAMAgEqRnJys5cuX6+233zYmupV+muA2ODjYa6LbRo0a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WbNGnTt31r333qvw8HB17NhRL730krH98OHDysvL86pZgwYN1KVLl1pbs9/+9rfavHmzPvvsM0nSRx99pB07dqhv376SqNnluJwaZWVlKSwsTJ07dzZiYmNj5e/vr+zs7Mt+rToVlzYqgsfj0UMPPaThw4erc+fOOnLkSLmYvLw8xcTEeK2LiIgwtp3/aFBt88UXX2ju3Ll64YUXjHXU67++++47lZSUGOMvExERoU8//dRHWVlPaWmpRo0apW7duunGG2+U9NO5EhgYqLCwMK/YiIgI5eXl+SBL33v99df14Ycfas+ePeW2US/UJry3msN77OXjfdacr776SgsXLlRKSoqefvpp7dmzR3/84x8VGBiopKQkoy4X+rdaW2s2duxYuVwutW7dWgEBASopKdHUqVM1cOBASaJml+FyapSXl6fw8HCv7XXq1FGjRo1M1ZE771Vk7Nix8vPzu+TPp59+qrlz5+qHH37QuHHjfJ2yT11uvc7373//W7fffrvuvfdeDR061EeZoyZITk7W/v379frrr/s6Fcv65ptv9MQTTygjI0NBQUG+TgdANcJ77OXhfda80tJS3XTTTXr22WfVsWNHDRs2TEOHDlV6erqvU7OslStXKiMjQ8uXL9eHH36opUuX6oUXXtDSpUt9nRougDvvVeT//b//p4ceeuiSMb/61a+0ZcsWZWVlyW63e23r3LmzBg4cqKVLlyoyMrLcTKJly5GRkRWat69cbr3KHDt2TL169dJvf/vbchPR1YZ6Xa4mTZooICDggvWobbW4mJEjRxqTiDRr1sxYHxkZqeLiYhUUFHjd5aittcvJydHx48d10003GetKSkq0fft2zZs3T5s2baJeqDV4b718vMdePt5nzWvatKnatm3rta5Nmzb6xz/+Iem/1335+flq2rSpEZOfn68OHTpUWZ5W8uSTT2rs2LEaMGCAJKldu3b6+uuvlZqaqqSkJGp2GS6nRpGRkeUmMD137pxOnDhh6t8rd96ryDXXXKPWrVtf8icwMFBz5szRRx99pNzcXOXm5mrDhg2SfprFdurUqZIkh8Oh7du3y+12G8d3Op1q1apVjXkE/HLrJf10x71nz57q1KmTFi9eLH9/79O6NtTrcgUGBqpTp07avHmzsa60tFSbN2+Ww+HwYWa+5/F4NHLkSK1evVpbtmwp91GLTp06yWazedXu0KFDOnr0aK2sXe/evbVv3z7jvSo3N9f4I2PZf1Mv1Ba8t/4y3mPN433WvG7dupX7CsLPPvtMLVq0kCTFxMQoMjLSq2Yul0vZ2dm1tmaFhYXlrp0DAgJUWloqiZpdjsupkcPhUEFBgXJycoyYLVu2qLS0VF26dLn8F7vKyfZQyQ4fPlxutvmCggJPRESE58EHH/Ts37/f8/rrr3tCQkI8L774ou8S9ZF//etfnuuvv97Tu3dvz7/+9S/Pt99+a/yUoV7eXn/9dY/dbvcsWbLEc/DgQc+wYcM8YWFhnry8PF+n5lMjRozwNGjQwLN161av86iwsNCIGT58uKd58+aeLVu2eD744AOPw+HwOBwOH2ZtLefPguzxUC/ULry3XhrvsRWD99lL2717t6dOnTqeqVOnej7//HNPRkaGJyQkxPPaa68ZMc8995wnLCzM8/bbb3s+/vhjT79+/TwxMTGeH3/80YeZ+05SUpLn2muv9axbt85z+PBhz5tvvulp0qSJZ8yYMUYMNfvpWx/27t3r2bt3r0eSZ8aMGZ69e/d6vv76a4/Hc3k1uv322z0dO3b0ZGdne3bs2OH5n//5H899991nKg+ad4u7UPPu8Xg8H330kefWW2/12O12z7XXXut57rnnfJOgjy1evNgj6YI/56Ne3ubOnetp3ry5JzAw0HPLLbd4du3a5euUfO5i59HixYuNmB9//NHz2GOPeRo2bOgJCQnx3H333V5/KKrtfn5RSb1Q2/DeenG8x1YM3md/2dq1az033nijx263e1q3bu1ZtGiR1/bS0lLPM88844mIiPDY7XZP7969PYcOHfJRtr7ncrk8TzzxhKd58+aeoKAgz69+9SvPn//8Z6+vWKZmHs+77757wfewpKQkj8dzeTX6/vvvPffdd5+nXr16ntDQUM/gwYM9P/zwg6k8/Dwej8fkkwEAAAAAAKAK8Zl3AAAAAAAsjuYdAAAAAACLo3kHAAAAAMDiaN4BAAAAALA4mncAAAAAACyO5h0AAAAAAIujeQcAAAAAwOJo3gEAAAAAsDiadwAAAAAALI7mHQAAAAAAi6N5BwAAAADA4mjeAQAAAACwuP8PaYskeA9C0m4AAAAASUVORK5CYII=\n"
},
"metadata": {}
}
],
"source": [
"df[(df['Quantity']>-50) &\n",
" (df['Quantity']<50) &\n",
" (df['UnitPrice']>0) &\n",
" (df['UnitPrice']<100)][['Quantity', 'UnitPrice']].hist(figsize=[12,4], bins=30)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:23.584264Z",
"iopub.status.busy": "2021-12-15T20:25:23.583784Z",
"iopub.status.idle": "2021-12-15T20:25:24.494000Z",
"shell.execute_reply": "2021-12-15T20:25:24.493618Z"
},
"colab": {
"base_uri": "https://localhost:8080/",
"height": 391
},
"id": "JbSWJJKUW_sn",
"outputId": "94aaf248-35ea-4e1d-fbf8-a1cf60b7778d"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1200x400 with 2 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA+UAAAF2CAYAAAAIrjlOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA8CklEQVR4nO3df3RU1bn/8U8SkolREsBIMBAM2oqmaEKB8KX+ggrEXIo/EEupaEAXYjtp0Vxqg60B6qKgKKXFKfFHFbG0UmyxKlRJYzW1RQjB6NUUKha8VEgQkAwkNcTJ+f7hylxiQpiTzMyeM3m/1nK1c87OmWceJif72WeffWIsy7IEAAAAAADCLtZ0AAAAAAAA9FQU5QAAAAAAGEJRDgAAAACAIRTlAAAAAAAYQlEOAAAAAIAhFOUAAAAAABhCUQ4AAAAAgCEU5QAAAAAAGEJRDgAAAACAIRTlADo0duxYjR071nQYAADAhpkzZyozMzNs70d/Aeg+inIgRN577z3NmDFDAwcOlMvlUnp6umbMmKGamhrTofnV1NRo4cKF2rt372nb7t+/XwsXLlR1dXXI4wIAINotXLhQMTExOnToUIf7hw0bFpRit7GxUQsXLtRrr712yhha/0tKSlJWVpZ+/OMfy+v1dvu9AQSml+kAgGj0hz/8QdOnT1e/fv10++23a8iQIdq7d69+9atf6bnnntO6det03XXXmQ5TNTU1WrRokcaOHdtuVH3z5s1tXu/fv1+LFi1SZmamcnJywhckAAAI2OOPP66Wlhb/68bGRi1atEiSTlnkr1q1SmeddZaOHz+uzZs3a/HixXr11Vf1t7/9TTExMZ2+3xf7CwDsoygHguyDDz7QLbfcovPPP18VFRU655xz/Pvmzp2rK664QjNmzNA777yjIUOGGIy0cwkJCaZDAAAANsXHx9v+malTpyo1NVWSdOedd+rGG2/UH/7wB7355psaM2ZMhz/T2NiopKQk+gtAEDB9HQiyZcuWqbGxUY899libglySUlNT9eijj+r48eNatmyZpFPf+9U6pexkTz31lL7+9a+rf//+crlcysrK0qpVq9r9bGZmpr7xjW/ojTfeUG5urhITE3X++edrzZo1/jarV6/WTTfdJEkaN26cf+pa6/S2k+8Re+211zRq1ChJ0qxZs/xtV69erQULFig+Pl4ff/xxuzjuuOMO9enTR59++mlgyQMAAO289tpriomJ0e9+9zstXrxYgwYNUmJioq6++mrt3r27TduT+xV79+7190UWLVrk//u9cOHCTt/v61//uiRpz549kj7vEwwbNkxVVVW68sorlZSUpHvvvde/74tX4D/99FMtXLhQF154oRITE3XuuedqypQp+uCDD/xtWlpatGLFCn3lK19RYmKi0tLSNGfOHH3yySddTRPgWBTlQJC9+OKLyszM1BVXXNHh/iuvvFKZmZl68cUXbR971apVOu+883Tvvffq4YcfVkZGhr773e/K4/G0a7t7925NnTpVEyZM0MMPP6y+fftq5syZeu+99/xxfP/735ck3XvvvXrmmWf0zDPP6OKLL253rIsvvlg/+clPJH1eaLe2vfLKK3XLLbfos88+07p169r8zIkTJ/Tcc8/pxhtvVGJiou3PCgAA2lq6dKk2bNigefPmaf78+XrzzTd18803n7L9Oeec4x+8v+GGG/x/v6dMmdLp+7QWz2effbZ/2+HDh5Wfn6+cnBytWLFC48aN6/BnfT6fvvGNb2jRokUaMWKEHn74Yc2dO1f19fV69913/e3mzJmjH/zgB7rsssv085//XLNmzdLatWuVl5en5ubmgHMCRAOmrwNBVF9fr/3795/2fvFLL71UL7zwgo4dO2br+K+//rrOOOMM/+vCwkJdc801Wr58udxud5u2u3btUkVFhX9w4Jvf/KYyMjL01FNP6aGHHtL555+vK664Qr/4xS80YcKETheTSUtLU35+vkpKSjRmzBjNmDGjzf4xY8bo17/+tQoLC/3bNm7cqE8++US33HKLrc8IAAA69umnn6q6uto/Zbxv376aO3eu3n33XQ0bNqxd+zPPPFNTp07Vd77zHV166aXt/n63OnLkiCT57yn/5S9/qbS0tDYXGGpra1VaWqo5c+Z0GuOaNWtUXl6u5cuX6+677/ZvLy4ulmVZkqQ33nhDTzzxhNauXatvf/vb/jbjxo3TNddco/Xr17fZDkQ7rpQDQdRaZPfu3bvTdq377RblJxfk9fX1OnTokK666ir961//Un19fZu2WVlZbf6YnnPOORo6dKj+9a9/2XrPQNx6663aunVrm2lpa9euVUZGhq666qqgvx8AAD3RrFmz2tzD3fp3vrt/24cOHapzzjlHQ4YM0Zw5c/SlL31JGzduVFJSkr+Ny+XSrFmzTnus3//+90pNTdX3vve9dvtab8tbv369UlJSNGHCBB06dMj/34gRI3TWWWfpL3/5S7c+D+A0XCkHgijQYvvYsWOKiYnxL6oSqL/97W9asGCBtmzZosbGxjb76uvrlZKS4n89ePDgdj/ft2/fkNyrNW3aNN11111au3atSkpKVF9fr5deekl33333aVdtBQAAHfvi39Av/m3v27evJHX7b/vvf/97JScnKz4+XoMGDdIFF1zQrs3AgQMDWtTtgw8+0NChQ9Wr16nLjPfff1/19fXq379/h/sPHjwYePBAFKAoB4IoJSVF6enpeueddzpt984772jQoEFKSEg4ZdHq8/navP7ggw909dVX66KLLtLy5cuVkZGhhIQEbdq0ST/72c/aPP5EkuLi4jo8buvUsWDq27evvvGNb/iL8ueee05NTU2nnCYHAEBP17reyn/+858O9zc2NrZbkyVUf9uvvPLK014oOHm2Xne1tLSof//+Wrt2bYf7v7hQLhDtKMqBIJs8ebIeffRRvfHGG7r88svb7f/rX/+qvXv3qqioSNLnBe3Ro0fbtfvwww/bvH7xxRfV1NSkF154oc1IeXemeNm5in26trfeequuu+46VVZWau3atRo+fLi+8pWvdDk2AACi2XnnnSfp8zVgMjIy2uxrbGzUvn37NHHixG6/T7hnrF1wwQXaunWrmpubT/l4tgsuuEB//vOfddlllwW12AecinvKgSCbN2+ekpKSNGfOHB0+fLjNviNHjujOO+9UcnKyf1G0Cy64QPX19W2urh84cEAbNmxo87Oto+Mnj4bX19frqaee6nKsZ555piR1OChgt21+fr5SU1P1wAMP6PXXX+cqOQAAnbj66quVkJCgVatWtZvt9thjj+mzzz5Tfn5+t9+n9b7wQP7WB8ONN96oQ4cO6ZFHHmm3r7UP881vflM+n0/3339/uzafffZZ2GIFIgVXyoEg+9KXvqQ1a9Zo+vTpuuSSS3T77bdryJAh2rt3r371q1/pk08+0bPPPqshQ4ZIkr71rW/phz/8oW644QZ9//vfV2Njo1atWqULL7xQO3bs8B934sSJSkhI0OTJkzVnzhwdP35cjz/+uPr3768DBw50KdacnBzFxcXpgQceUH19vVwul/856F90wQUXqE+fPiotLVXv3r115plnavTo0f7PER8fr299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SE5O5hfBBvIVOHJlD/myJ5rylZKSYjoEhFiw+w3R9P0PF3JmHzmzj5zZR866JhQD+VwaAAAAAADAEIpyAAAAAAAMoSg3wOVyacGCBXK5XKZDcQTyFThyZQ/5sod8oSfj+28fObOPnNlHzuwjZ10Tyrw5bqE3AAAAAACiBVfKAQAAAAAwhKIcAAAAAABDKMoBAAAAADCEohwAAAAAAEMoyg1pampSTk6OYmJiVF1d3WbfO++8oyuuuEKJiYnKyMjQgw8+aCZIg/bu3avbb79dQ4YM0RlnnKELLrhACxYs0IkTJ9q0I1dteTweZWZmKjExUaNHj9a2bdtMh2TckiVLNGrUKPXu3Vv9+/fX9ddfr127drVp8+mnn8rtduvss8/WWWedpRtvvFF1dXWGIo4sS5cuVUxMjO666y7/NvKFnoZz66lxju0+zrOB+eijjzRjxgydffbZOuOMM3TJJZdo+/bt/v2WZamkpETnnnuuzjjjDI0fP17vv/++wYjN8/l8uu+++9r0p++//36dvM53T89bRUWFJk+erPT0dMXExOj5559vsz+Q/Bw5ckQ333yzkpOT1adPH91+++06fvy4rTgoyg255557lJ6e3m671+vVxIkTdd5556mqqkrLli3TwoUL9dhjjxmI0pydO3eqpaVFjz76qN577z397Gc/U2lpqe69915/G3LV1rp161RUVKQFCxZox44dys7OVl5eng4ePGg6NKNef/11ud1uvfnmmyorK1Nzc7MmTpyohoYGf5u7775bL774otavX6/XX39d+/fv15QpUwxGHRkqKyv16KOP6tJLL22znXyhJ+Hc2jnOsd3DeTYwn3zyiS677DLFx8frT3/6k2pqavTwww+rb9++/jYPPvigfvGLX6i0tFRbt27VmWeeqby8PH366acGIzfrgQce0KpVq/TII4/oH//4hx544AE9+OCDWrlypb9NT89bQ0ODsrOz5fF4OtwfSH5uvvlmvffeeyorK9NLL72kiooK3XHHHfYCsRB2mzZtsi666CLrvffesyRZb731ln/fL3/5S6tv375WU1OTf9sPf/hDa+jQoQYijSwPPvigNWTIEP9rctVWbm6u5Xa7/a99Pp+Vnp5uLVmyxGBUkefgwYOWJOv111+3LMuyjh49asXHx1vr16/3t/nHP/5hSbK2bNliKkzjjh07Zn35y1+2ysrKrKuuusqaO3euZVnkCz0P51Z7OMcGjvNs4H74wx9al19++Sn3t7S0WAMGDLCWLVvm33b06FHL5XJZv/3tb8MRYkSaNGmSddttt7XZNmXKFOvmm2+2LIu8fZEka8OGDf7XgeSnpqbGkmRVVlb62/zpT3+yYmJirI8++ijg9+ZKeZjV1dVp9uzZeuaZZ5SUlNRu/5YtW3TllVcqISHBvy0vL0+7du3SJ598Es5QI059fb369evnf02u/s+JEydUVVWl8ePH+7fFxsZq/Pjx2rJli8HIIk99fb0k+b9LVVVVam5ubpO7iy66SIMHD+7RuXO73Zo0aVKbvEjkCz0L51b7OMcGjvNs4F544QWNHDlSN910k/r376/hw4fr8ccf9+/fs2ePamtr2+QsJSVFo0eP7rE5k6Svfe1rKi8v1z//+U9J0ttvv6033nhD+fn5ksjb6QSSny1btqhPnz4aOXKkv8348eMVGxurrVu3BvxevYIXNk7HsizNnDlTd955p0aOHKm9e/e2a1NbW6shQ4a02ZaWlubfd/I0nZ5k9+7dWrlypR566CH/NnL1fw4dOiSfz+f//K3S0tK0c+dOQ1FFnpaWFt1111267LLLNGzYMEmff1cSEhLUp0+fNm3T0tJUW1trIErznn32We3YsUOVlZXt9pEv9CScW+3hHBs4zrP2/Otf/9KqVatUVFSke++9V5WVlfr+97+vhIQEFRQU+PPS0e9qT82ZJBUXF8vr9eqiiy5SXFycfD6fFi9erJtvvlmSyNtpBJKf2tpa9e/fv83+Xr16qV+/frZyyJXyICguLlZMTEyn/+3cuVMrV67UsWPHNH/+fNMhGxNork720Ucf6ZprrtFNN92k2bNnG4oc0cDtduvdd9/Vs88+azqUiLVv3z7NnTtXa9euVWJioulwADgI59jAcJ61r6WlRV/96lf105/+VMOHD9cdd9yh2bNnq7S01HRoEe13v/ud1q5dq9/85jfasWOHnn76aT300EN6+umnTYeGL+BKeRD893//t2bOnNlpm/PPP1+vvvqqtmzZIpfL1WbfyJEjdfPNN+vpp5/WgAED2q2u2fp6wIABQY3bhEBz1Wr//v0aN26cvva1r7VbwC3ac2VHamqq4uLiOsxHT8vFqRQWFvoX3xg0aJB/+4ABA3TixAkdPXq0zVWJnpq7qqoqHTx4UF/96lf923w+nyoqKvTII4/olVdeIV/oMTi3Bo5zbOA4z9p37rnnKisrq822iy++WL///e8l/V+/r66uTueee66/TV1dnXJycsIWZ6T5wQ9+oOLiYn3rW9+SJF1yySX68MMPtWTJEhUUFJC30wgkPwMGDGi38Odnn32mI0eO2Pp95Up5EJxzzjm66KKLOv0vISFBv/jFL/T222+rurpa1dXV2rRpk6TPV3ZdvHixJGnMmDGqqKhQc3Oz//hlZWUaOnRoVEzHDjRX0udXyMeOHasRI0boqaeeUmxs269rtOfKjoSEBI0YMULl5eX+bS0tLSovL9eYMWMMRmaeZVkqLCzUhg0b9Oqrr7a75WHEiBGKj49vk7tdu3bpf//3f3tk7q6++mr9z//8j/88VV1d7R84bP3/5As9BefW0+Mcax/nWfsuu+yydo/a++c//6nzzjtPkjRkyBANGDCgTc68Xq+2bt3aY3MmSY2Nje36z3FxcWppaZFE3k4nkPyMGTNGR48eVVVVlb/Nq6++qpaWFo0ePTrwN+vmInXohj179rRbff3o0aNWWlqadcstt1jvvvuu9eyzz1pJSUnWo48+ai5QA/79739bX/rSl6yrr77a+ve//20dOHDA/18rctXWs88+a7lcLmv16tVWTU2Ndccdd1h9+vSxamtrTYdm1He+8x0rJSXFeu2119p8jxobG/1t7rzzTmvw4MHWq6++am3fvt0aM2aMNWbMGINRR5aTVwW2LPKFnoVza+c4xwYH59nObdu2zerVq5e1ePFi6/3337fWrl1rJSUlWb/+9a/9bZYuXWr16dPH+uMf/2i988471nXXXWcNGTLE+s9//mMwcrMKCgqsgQMHWi+99JK1Z88e6w9/+IOVmppq3XPPPf42PT1vx44ds9566y3rrbfesiRZy5cvt9566y3rww8/tCwrsPxcc8011vDhw62tW7dab7zxhvXlL3/Zmj59uq04KMoN6qgotyzLevvtt63LL7/ccrlc1sCBA62lS5eaCdCgp556ypLU4X8nI1dtrVy50ho8eLCVkJBg5ebmWm+++abpkIw71ffoqaee8rf5z3/+Y333u9+1+vbtayUlJVk33HBDmwGgnu6LnUXyhZ6Gc+upcY4NDs6zp/fiiy9aw4YNs1wul3XRRRdZjz32WJv9LS0t1n333WelpaVZLpfLuvrqq61du3YZijYyeL1ea+7cudbgwYOtxMRE6/zzz7d+9KMftXmccE/P21/+8pcOz2EFBQWWZQWWn8OHD1vTp0+3zjrrLCs5OdmaNWuWdezYMVtxxFiWZdm8kg8AAAAAAIKAe8oBAAAAADCEohwAAAAAAEMoygEAAAAAMISiHAAAAAAAQyjKAQAAAAAwhKIcAAAAAABDKMoBAAAAADCEohwAAAAAAEMoygEAAAAAMISiHAAAAAAAQyjKAQAAAAAwhKIcAAAAAABD/j8nbAaz0E9J8AAAAABJRU5ErkJggg==\n"
},
"metadata": {}
}
],
"source": [
"df[(df['Quantity']>-50) &\n",
" (df['Quantity']<50) &\n",
" (df['UnitPrice']>0) &\n",
" (df['UnitPrice']<100)][['Quantity', 'UnitPrice']].hist(figsize=[12,4], bins=30, log=True)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:24.504460Z",
"iopub.status.busy": "2021-12-15T20:25:24.504086Z",
"iopub.status.idle": "2021-12-15T20:25:26.468550Z",
"shell.execute_reply": "2021-12-15T20:25:26.466711Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "5QysMacBW_so",
"outputId": "e3356521-63c3-404c-e8db-5ed6a0407162"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" Country CustomerID ... StockCode UnitPrice\n",
"46 United Kingdom 13748.0 ... 22086 2.55\n",
"83 United Kingdom 15291.0 ... 21733 2.55\n",
"96 United Kingdom 14688.0 ... 21212 0.42\n",
"102 United Kingdom 14688.0 ... 85071B 0.38\n",
"176 United Kingdom 16029.0 ... 85099C 1.65\n",
"... ... ... ... ... ...\n",
"14784 United Kingdom 15061.0 ... 22423 10.95\n",
"14785 United Kingdom 15061.0 ... 22075 1.45\n",
"14788 United Kingdom 15061.0 ... 17038 0.07\n",
"14974 United Kingdom 14739.0 ... 21704 0.72\n",
"14980 United Kingdom 14739.0 ... 22178 1.06\n",
"\n",
"[258 rows x 8 columns]\n"
]
}
],
"source": [
"filter_quantity_price = df[(df['Quantity'] > 50) & (df['UnitPrice'] < 100)]\n",
"print(filter_quantity_price)\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xG1_wb5RW_so"
},
"source": [
"## Arithmetic Operations"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CxqA7gO-W_so"
},
"source": [
"Numeric values"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:26.483774Z",
"iopub.status.busy": "2021-12-15T20:25:26.482084Z",
"iopub.status.idle": "2021-12-15T20:25:26.907406Z",
"shell.execute_reply": "2021-12-15T20:25:26.906448Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "HWoI0tYcW_so",
"outputId": "727db684-740b-45bf-9e4e-3887674b3e8c"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 6\n",
"1 6\n",
"2 8\n",
"3 6\n",
"4 6\n",
"Name: Quantity, dtype: int64"
]
},
"metadata": {},
"execution_count": 34
}
],
"source": [
"df['Quantity'].head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:26.912916Z",
"iopub.status.busy": "2021-12-15T20:25:26.910149Z",
"iopub.status.idle": "2021-12-15T20:25:27.361783Z",
"shell.execute_reply": "2021-12-15T20:25:27.362723Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "I6Rs0pTAW_sp",
"outputId": "68aa067b-b70c-4030-8acf-a2b36310fc52"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 2.55\n",
"1 3.39\n",
"2 2.75\n",
"3 3.39\n",
"4 3.39\n",
"Name: UnitPrice, dtype: float64"
]
},
"metadata": {},
"execution_count": 42
}
],
"source": [
"df['UnitPrice'].head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:27.383414Z",
"iopub.status.busy": "2021-12-15T20:25:27.374098Z",
"iopub.status.idle": "2021-12-15T20:25:27.387546Z",
"shell.execute_reply": "2021-12-15T20:25:27.388753Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "wbibhbn6W_sp",
"outputId": "d0b6b88b-6282-4901-fea1-94d2e94c773d"
},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"/usr/local/lib/python3.10/dist-packages/eland/field_mappings.py:715: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n",
" self._mappings_capabilities = self._mappings_capabilities.append(\n"
]
}
],
"source": [
"product = df['Quantity'] * df['UnitPrice']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:27.398754Z",
"iopub.status.busy": "2021-12-15T20:25:27.397557Z",
"iopub.status.idle": "2021-12-15T20:25:27.818022Z",
"shell.execute_reply": "2021-12-15T20:25:27.819640Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "2FstW8ZCW_sp",
"outputId": "b55d687e-6b7d-48a8-8815-e64bc6ebf6dd"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 15.30\n",
"1 20.34\n",
"2 22.00\n",
"3 20.34\n",
"4 20.34\n",
"dtype: float64"
]
},
"metadata": {},
"execution_count": 44
}
],
"source": [
"product.head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Pd2zMWGBW_sp"
},
"source": [
"String concatenation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {
"iopub.execute_input": "2021-12-15T20:25:27.837007Z",
"iopub.status.busy": "2021-12-15T20:25:27.836370Z",
"iopub.status.idle": "2021-12-15T20:25:29.072872Z",
"shell.execute_reply": "2021-12-15T20:25:29.074153Z"
},
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "5MpSfh0fW_sp",
"outputId": "e0c52ddf-19bc-40af-813a-75c7e808bef6"
},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"/usr/local/lib/python3.10/dist-packages/eland/field_mappings.py:715: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n",
" self._mappings_capabilities = self._mappings_capabilities.append(\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 United Kingdom85123A\n",
"1 United Kingdom71053\n",
"2 United Kingdom84406B\n",
"3 United Kingdom84029G\n",
"4 United Kingdom84029E\n",
" ... \n",
"14995 United Kingdom72349B\n",
"14996 United Kingdom72741\n",
"14997 United Kingdom22762\n",
"14998 United Kingdom21773\n",
"14999 United Kingdom22149\n",
"Length: 15000, dtype: object"
]
},
"metadata": {},
"execution_count": 45
}
],
"source": [
"df['Country'] + df['StockCode']"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.6"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
},
"colab": {
"provenance": []
}
},
"nbformat": 4,
"nbformat_minor": 0
}