From dee17552c581dbba99ffb606b65cbb4dba757b5b Mon Sep 17 00:00:00 2001 From: bibibim Date: Thu, 15 Aug 2024 20:18:29 +0900 Subject: [PATCH] =?UTF-8?q?Colab=EC=9D=84=20=ED=86=B5=ED=95=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EB=90=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sungon/week4_stock.ipynb | 841 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 841 insertions(+) create mode 100644 sungon/week4_stock.ipynb diff --git a/sungon/week4_stock.ipynb b/sungon/week4_stock.ipynb new file mode 100644 index 0000000..5437e20 --- /dev/null +++ b/sungon/week4_stock.ipynb @@ -0,0 +1,841 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "mount_file_id": "1v6bsLfz_O0tuas0pur3R8ZVDZR770UNx", + "authorship_tag": "ABX9TyPazXODLzfydf31FmMFAvuh", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Prepare Environment\n", + "\n", + "Install Dependencies:\n", + "\n", + "\n", + "1. Java 8\n", + "2. Apache Spark with hadoop and\n", + "3. Findspark (used to locate the spark in the system)\n", + "\n", + "> If you have issues with spark version, please upgrade to the latest version from [here](https://archive.apache.org/dist/spark/)." + ], + "metadata": { + "id": "3bwTrStDcbtu" + } + }, + { + "cell_type": "code", + "source": [ + "### java\n", + "!apt-get install openjdk-8-jdk-headless -qq > /dev/null\n", + "\n", + "### spark & pyspark\n", + "#!wget -q http://archive.apache.org/dist/spark/spark-3.5.1/spark-3.5.1-bin-hadoop3.tgz\n", + "!cp /content/drive/MyDrive/2024_pyspark/spark-3.5.1-bin-hadoop3.tgz /content/\n", + "!tar xf spark-3.5.1-bin-hadoop3.tgz\n", + "!pip install -q findspark matplotlib\n", + "\n", + "### test data\n", + "!cp -r /content/drive/MyDrive/2024_pyspark/stock_data /content/\n", + "\n", + "# 구글 드라이브로 직접 csv 파일을 업로드하는 것 보다 압축파일 업로드 -> 마운트 -> 복사 -> 압축해제가 더 빠름\n", + "# 압축해제만 20초 소요 / 3400종목 / 3.61GB\n", + "!unzip -qq /content/stock_data/stock_nasdaq.zip" + ], + "metadata": { + "id": "pVHJclBtea4e", + "collapsed": true + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C3x0ZRLxjMVr" + }, + "source": [ + "Set Environment Variables:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "sdOOq4twHN1K", + "collapsed": true + }, + "outputs": [], + "source": [ + "import os\n", + "os.environ[\"JAVA_HOME\"] = \"/usr/lib/jvm/java-8-openjdk-amd64\"\n", + "os.environ[\"SPARK_HOME\"] = \"/content/spark-3.5.1-bin-hadoop3\"" + ] + }, + { + "cell_type": "code", + "source": [ + "import findspark\n", + "findspark.init()\n", + "\n", + "from pyspark.sql import SparkSession\n", + "\n", + "spark = SparkSession.builder\\\n", + " .master(\"local[*]\")\\\n", + " .getOrCreate()\n", + "spark.conf.set(\"spark.sql.repl.eagerEval.enabled\", True) # Property used to format output tables better\n", + "spark" + ], + "metadata": { + "collapsed": true, + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Xy1wTKEIEFeG", + "outputId": "20e5a294-886b-441e-c374-f358f3572260" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "\n", + "
\n", + "

SparkSession - in-memory

\n", + " \n", + "
\n", + "

SparkContext

\n", + "\n", + "

Spark UI

\n", + "\n", + "
\n", + "
Version
\n", + "
v3.5.1
\n", + "
Master
\n", + "
local[*]
\n", + "
AppName
\n", + "
pyspark-shell
\n", + "
\n", + "
\n", + " \n", + "
\n", + " " + ] + }, + "metadata": {}, + "execution_count": 3 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from pyspark.sql.dataframe import DataFrame\n", + "\n", + "# Define a Peek Function\n", + "def peek(self, n=10):\n", + " self.show(n)\n", + " return self\n", + "\n", + "# Monkey Patch the DataFrame Calss\n", + "DataFrame.peek = peek" + ], + "metadata": { + "id": "4kAxUQ8h9aW1" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# 주식 데이터 분석\n" + ], + "metadata": { + "id": "6U9GQvQPTD1C" + } + }, + { + "cell_type": "markdown", + "source": [ + "## 데이터 준비" + ], + "metadata": { + "id": "C3NlmBpP-qTz" + } + }, + { + "cell_type": "code", + "source": [ + "from pyspark.sql.functions import col, avg, count, year, datediff, expr, min, max, filter, count_if, when, trim, to_date, month, input_file_name, regexp_extract\n", + "from pyspark.sql.types import StructType, StructField, IntegerType, StringType, TimestampType, DoubleType\n", + "\n", + "stock_lables = [\n", + " ('date', StringType()),\n", + " ('low', DoubleType()),\n", + " ('open', DoubleType()),\n", + " ('volumn', IntegerType()),\n", + " ('high', DoubleType()),\n", + " ('close', DoubleType()),\n", + " ('adjusted_close', StringType()),\n", + "]\n", + "stock_schema = StructType([StructField(x[0], x[1], True) for x in stock_lables])\n", + "\n", + "# NASAQ / 1565종목 / 841MB\n", + "# input_file_name() : file:///content/nasdaq_csv/AAPL.csv\n", + "stock_df = spark.read.csv('nasdaq_csv/', header=True, sep=\",\", schema=stock_schema)\n", + "print(f'before filtereing weather_df.count(): {stock_df.count():,}')\n", + "\n", + "# add & type case column\n", + "stock_df = stock_df.withColumn('ticker', regexp_extract(input_file_name(), \"([^/]+)\\.csv\", 1))\\\n", + " .withColumn('date', to_date('date', 'dd-MM-yyyy'))\\\n", + " .withColumn(\"volumn\", stock_df[\"volumn\"].cast(IntegerType()))\\\n", + "\n", + "# filter\n", + "stock_df = stock_df.filter(stock_df.date.isNotNull())\\\n", + " .filter(stock_df.low.isNotNull())\\\n", + " .filter(stock_df.open.isNotNull())\\\n", + " .filter(stock_df.volumn.isNotNull())\\\n", + " .filter(stock_df.high.isNotNull())\\\n", + " .filter(stock_df.close.isNotNull())\\\n", + " .filter(stock_df.adjusted_close.isNotNull())\n", + "\n", + "# add column\n", + "from pyspark.sql.functions import year, month, weekofyear, dayofmonth\n", + "stock_df = stock_df.withColumn('year', year(stock_df.date))\\\n", + " .withColumn('month', month(stock_df.date))\\\n", + " .withColumn('day', dayofmonth(stock_df.date))\\\n", + " .withColumn('week', weekofyear(stock_df.date))\n", + "\n", + "print(f'after filtereing weather_df.count(): {stock_df.count():,}')\n", + "stock_df.show(3)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "bvV2ZCP0h5MO", + "outputId": "925ffcef-3ff0-48d2-eb57-891a2a448127" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "before filtereing weather_df.count(): 8,752,326\n", + "after filtereing weather_df.count(): 7,998,945\n", + "+----------+-------------------+----+------+-------------------+-------------------+-------------------+------+----+-----+---+----+\n", + "| date| low|open|volumn| high| close| adjusted_close|ticker|year|month|day|week|\n", + "+----------+-------------------+----+------+-------------------+-------------------+-------------------+------+----+-----+---+----+\n", + "|1973-02-21|0.39506199955940247| 0.0| 15188|0.39506199955940247|0.39506199955940247|0.39506199955940247| DIOD|1973| 2| 21| 8|\n", + "|1973-02-22| 0.3703700006008148| 0.0| 9113| 0.3703700006008148| 0.3703700006008148| 0.3703700006008148| DIOD|1973| 2| 22| 8|\n", + "|1973-02-23|0.34567898511886597| 0.0| 3038|0.34567898511886597|0.34567898511886597|0.34567898511886597| DIOD|1973| 2| 23| 8|\n", + "+----------+-------------------+----+------+-------------------+-------------------+-------------------+------+----+-----+---+----+\n", + "only showing top 3 rows\n", + "\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### 아이디어\n", + "\n", + "전체\n", + "- 가장 거래량이 적었던 날\n", + "- 가장 거래량이 많았던 날\n", + "- 가장 많은 종목이 오늘 날\n", + "- 가장 많은 종목이 내린 날\n", + "- 가장 오랫동안 오른 종목 e.g. 10거래일 연속" + ], + "metadata": { + "id": "ttlxq1ml7Ry7" + } + }, + { + "cell_type": "markdown", + "source": [ + "데이터 준비" + ], + "metadata": { + "id": "RkfOR3_M0cQS" + } + }, + { + "cell_type": "code", + "source": [ + "# 성능 높이기 : dataframe 을 메모리에 저장하여 연산 속도를 높임\n", + "stock_df.cache()\n", + "# stock_2020s_df = stock_df.filter('date >= \"2020-01-01\"')\n", + "# stock_2020s_df.cache()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "id": "S5FdKwy7zncX", + "outputId": "7cb1bd25-a59e-4d10-9d64-949ce75a8283" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "+----------+-------------------+------------------+------+-------------------+-------------------+-------------------+------+----+-----+---+----+\n", + "| date| low| open|volumn| high| close| adjusted_close|ticker|year|month|day|week|\n", + "+----------+-------------------+------------------+------+-------------------+-------------------+-------------------+------+----+-----+---+----+\n", + "|1973-02-21|0.39506199955940247| 0.0| 15188|0.39506199955940247|0.39506199955940247|0.39506199955940247| DIOD|1973| 2| 21| 8|\n", + "|1973-02-22| 0.3703700006008148| 0.0| 9113| 0.3703700006008148| 0.3703700006008148| 0.3703700006008148| DIOD|1973| 2| 22| 8|\n", + "|1973-02-23|0.34567898511886597| 0.0| 3038|0.34567898511886597|0.34567898511886597|0.34567898511886597| DIOD|1973| 2| 23| 8|\n", + "|1973-02-26|0.34567898511886597| 0.0| 1519|0.34567898511886597|0.34567898511886597|0.34567898511886597| DIOD|1973| 2| 26| 9|\n", + "|1973-02-27|0.34567898511886597| 0.0| 29869|0.34567898511886597|0.34567898511886597|0.34567898511886597| DIOD|1973| 2| 27| 9|\n", + "|1973-02-28|0.34567898511886597| 0.0| 1519|0.34567898511886597|0.34567898511886597|0.34567898511886597| DIOD|1973| 2| 28| 9|\n", + "|1973-03-01| 0.3209879994392395| 0.0| 18225| 0.3209879994392395| 0.3209879994392395| 0.3209879994392395| DIOD|1973| 3| 1| 9|\n", + "|1973-03-02| 0.3209879994392395| 0.0| 20250| 0.3209879994392395| 0.3209879994392395| 0.3209879994392395| DIOD|1973| 3| 2| 9|\n", + "|1973-03-05|0.34567898511886597| 0.0| 6075|0.34567898511886597|0.34567898511886597|0.34567898511886597| DIOD|1973| 3| 5| 10|\n", + "|1973-03-06| 0.3209879994392395| 0.0| 1519| 0.3209879994392395| 0.3209879994392395| 0.3209879994392395| DIOD|1973| 3| 6| 10|\n", + "|1973-03-07|0.34567898511886597| 0.0| 8100|0.34567898511886597|0.34567898511886597|0.34567898511886597| DIOD|1973| 3| 7| 10|\n", + "|1973-03-08| 0.3209879994392395| 0.0| 7088| 0.3209879994392395| 0.3209879994392395| 0.3209879994392395| DIOD|1973| 3| 8| 10|\n", + "|1973-03-09| 0.3209879994392395| 0.0| 10125| 0.3209879994392395| 0.3209879994392395| 0.3209879994392395| DIOD|1973| 3| 9| 10|\n", + "|1973-03-12| 0.3703700006008148| 0.0| 20250| 0.3703700006008148| 0.3703700006008148| 0.3703700006008148| DIOD|1973| 3| 12| 11|\n", + "|1973-03-13| 0.3703700006008148| 0.0| 15188| 0.3703700006008148| 0.3703700006008148| 0.3703700006008148| DIOD|1973| 3| 13| 11|\n", + "|1973-03-14|0.34567898511886597| 0.0| 5569|0.34567898511886597|0.34567898511886597|0.34567898511886597| DIOD|1973| 3| 14| 11|\n", + "|1973-03-15| 0.3209879994392395| 0.0| 3038| 0.3209879994392395| 0.3209879994392395| 0.3209879994392395| DIOD|1973| 3| 15| 11|\n", + "|1973-03-16| 0.3209879994392395|0.3209879994392395| 0| 0.3209879994392395| 0.3209879994392395| 0.3209879994392395| DIOD|1973| 3| 16| 11|\n", + "|1973-03-19| 0.3209879994392395| 0.0| 7088| 0.3209879994392395| 0.3209879994392395| 0.3209879994392395| DIOD|1973| 3| 19| 12|\n", + "|1973-03-20| 0.3209879994392395| 0.0| 1519| 0.3209879994392395| 0.3209879994392395| 0.3209879994392395| DIOD|1973| 3| 20| 12|\n", + "+----------+-------------------+------------------+------+-------------------+-------------------+-------------------+------+----+-----+---+----+\n", + "only showing top 20 rows" + ], + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
datelowopenvolumnhighcloseadjusted_closetickeryearmonthdayweek
1973-02-210.395061999559402470.0151880.395061999559402470.395061999559402470.39506199955940247DIOD19732218
1973-02-220.37037000060081480.091130.37037000060081480.37037000060081480.3703700006008148DIOD19732228
1973-02-230.345678985118865970.030380.345678985118865970.345678985118865970.34567898511886597DIOD19732238
1973-02-260.345678985118865970.015190.345678985118865970.345678985118865970.34567898511886597DIOD19732269
1973-02-270.345678985118865970.0298690.345678985118865970.345678985118865970.34567898511886597DIOD19732279
1973-02-280.345678985118865970.015190.345678985118865970.345678985118865970.34567898511886597DIOD19732289
1973-03-010.32098799943923950.0182250.32098799943923950.32098799943923950.3209879994392395DIOD1973319
1973-03-020.32098799943923950.0202500.32098799943923950.32098799943923950.3209879994392395DIOD1973329
1973-03-050.345678985118865970.060750.345678985118865970.345678985118865970.34567898511886597DIOD19733510
1973-03-060.32098799943923950.015190.32098799943923950.32098799943923950.3209879994392395DIOD19733610
1973-03-070.345678985118865970.081000.345678985118865970.345678985118865970.34567898511886597DIOD19733710
1973-03-080.32098799943923950.070880.32098799943923950.32098799943923950.3209879994392395DIOD19733810
1973-03-090.32098799943923950.0101250.32098799943923950.32098799943923950.3209879994392395DIOD19733910
1973-03-120.37037000060081480.0202500.37037000060081480.37037000060081480.3703700006008148DIOD197331211
1973-03-130.37037000060081480.0151880.37037000060081480.37037000060081480.3703700006008148DIOD197331311
1973-03-140.345678985118865970.055690.345678985118865970.345678985118865970.34567898511886597DIOD197331411
1973-03-150.32098799943923950.030380.32098799943923950.32098799943923950.3209879994392395DIOD197331511
1973-03-160.32098799943923950.320987999439239500.32098799943923950.32098799943923950.3209879994392395DIOD197331611
1973-03-190.32098799943923950.070880.32098799943923950.32098799943923950.3209879994392395DIOD197331912
1973-03-200.32098799943923950.015190.32098799943923950.32098799943923950.3209879994392395DIOD197332012
\n", + "only showing top 20 rows\n" + ] + }, + "metadata": {}, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "source": [ + "# the most vloumn date\n", + "from pyspark.sql.functions import sum as _sum\n", + "\n", + "stock_df.groupBy('date')\\\n", + " .agg(_sum('volumn').alias('volumn_sum'))\\\n", + " .orderBy(col('volumn_sum').desc())\\\n", + " .show(10)\n", + "\n", + "# the most volumn by year & year of week\n", + "stock_df.groupBy('year', 'week')\\\n", + " .agg(_sum('volumn').alias('volumn_sum'))\\\n", + " .orderBy(col('volumn_sum').desc())\\\n", + " .show(10)\n", + "\n", + "# the most volumn by year & month\n", + "stock_df.groupBy('year', 'month')\\\n", + " .agg(_sum('volumn').alias('volumn_sum'))\\\n", + " .orderBy(col('volumn_sum').desc())\\\n", + " .show(10)\n", + "\n", + "# the most volumn by year\n", + "stock_df.groupBy('year')\\\n", + " .agg(_sum('volumn').alias('volumn_sum'))\\\n", + " .orderBy(col('volumn_sum').desc())\\\n", + " .show(10)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "rGStj1cwyjz5", + "outputId": "879d6e25-115b-401b-ab6c-63551d0d6d8f" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "+----------+----------+\n", + "| date|volumn_sum|\n", + "+----------+----------+\n", + "|2008-10-06|4832647902|\n", + "|2008-10-16|4689054057|\n", + "|2008-09-18|4536492718|\n", + "|2007-04-25|4472029047|\n", + "|2008-10-23|4412837988|\n", + "|2010-05-07|4411887653|\n", + "|2008-10-14|4398442274|\n", + "|2008-11-13|4287004436|\n", + "|2008-02-07|4274270252|\n", + "|2007-04-26|4265902863|\n", + "+----------+----------+\n", + "only showing top 10 rows\n", + "\n", + "+----+----+-----------+\n", + "|year|week| volumn_sum|\n", + "+----+----+-----------+\n", + "|2008| 42|20317783656|\n", + "|2008| 41|19067046118|\n", + "|2008| 38|18421997411|\n", + "|2008| 44|17881196734|\n", + "|2008| 2|17445809097|\n", + "|2008| 47|17404327446|\n", + "|2010| 4|16678135602|\n", + "|2007| 17|16492550731|\n", + "|2011| 32|16283029038|\n", + "|2008| 5|16207069170|\n", + "+----+----+-----------+\n", + "only showing top 10 rows\n", + "\n", + "+----+-----+-----------+\n", + "|year|month| volumn_sum|\n", + "+----+-----+-----------+\n", + "|2008| 10|80385626601|\n", + "|2008| 1|66091241952|\n", + "|2008| 7|60532229605|\n", + "|2008| 9|59968305336|\n", + "|2007| 11|59443688201|\n", + "|2008| 2|57903330330|\n", + "|2007| 8|57821596259|\n", + "|2008| 11|57781602151|\n", + "|2008| 3|56988572975|\n", + "|2020| 3|56926146548|\n", + "+----+-----+-----------+\n", + "only showing top 10 rows\n", + "\n", + "+----+------------+\n", + "|year| volumn_sum|\n", + "+----+------------+\n", + "|2008|692804039699|\n", + "|2007|583361045628|\n", + "|2009|536346663126|\n", + "|2010|523955955348|\n", + "|2006|502110021245|\n", + "|2020|495383172848|\n", + "|2011|476044949621|\n", + "|2021|442888183019|\n", + "|2005|438569967014|\n", + "|2022|421371368602|\n", + "+----+------------+\n", + "only showing top 10 rows\n", + "\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# the most volumn by year\n", + "volumn_sum_pandas = stock_df.groupBy('year', 'month')\\\n", + " .agg(_sum('volumn').alias('volumn_sum'))\\\n", + " .orderBy(col('year').asc(), col('month').asc())\\\n", + " .toPandas()\n", + "\n", + "plt.bar(volumn_sum_pandas['year'], volumn_sum_pandas['volumn_sum'])\n", + "plt.xlabel('year')\n", + "plt.ylabel('sum of volumn')\n", + "plt.title('Stock trading volume by year')\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 472 + }, + "id": "4FtANsUL5mRS", + "outputId": "a6f322be-5c3b-4ae1-86fe-fcab90f57fca" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAHHCAYAAACRAnNyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA+1klEQVR4nO3dd3xUVf7/8fckhAmQQgs9BAy9VzFIEWmySF2KiBBApYPAIpBVQVwx4CqCwIq6SllUitSVFQRp0hQQkIAgHaRFSgh1Asn5/eEv83VMgAxMMjfk9Xw85vHg3nvmzueemZB3zj33js0YYwQAAGBBPt4uAAAA4E4IKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKoAHrFu3TjabTV9++aW3S0mzJ554Qk888YRz+dixY7LZbJo5c6bXavKU5Pdj3bp13i7Fba+//rpsNpvOnz/v7VIASyCoINPas2ePOnTooLCwMPn7+6to0aJq2rSppkyZ4tLurbfe0pIlS7xTZBqcPn1ar7/+unbt2uXtUgDAcggqyJQ2b96sWrVqaffu3XrxxRc1depUvfDCC/Lx8dHkyZNd2maGoDJ27FivB5WwsDDduHFD3bp182odAPBH2bxdAHA/xo0bp+DgYG3btk25c+d22RYbG+udojLI9evXlTNnTo/v12azyd/f3+P7Be7l2rVrypUrl7fLgEUxooJM6fDhw6pYsWKKkCJJBQoUcP7bZrPp2rVrmjVrlmw2m2w2m3r06OHcvnPnTrVo0UJBQUEKCAhQ48aNtXXr1hT7jIuL09ChQ1WiRAnZ7XYVK1ZM3bt3v+s8AofDoaefflrBwcHavHlzqm3WrVun2rVrS5J69uzprDF5nsgTTzyhSpUqaceOHWrQoIFy5sypv//975KkpUuXqmXLlipSpIjsdrvCw8P1j3/8Q4mJiSle56OPPlJ4eLhy5MihRx99VN99912KNqnNUenRo4cCAgJ06tQptW3bVgEBAQoJCdHw4cNTvM6FCxfUrVs3BQUFKXfu3IqMjNTu3bvvOe9l+/btstlsmjVrVoptK1eulM1m01dffeVcl9b37M9KlCjh8t4n+/NcneT5LfPnz9fYsWNVtGhRBQYGqkOHDrp8+bIcDoeGDBmiAgUKKCAgQD179pTD4Uix3zlz5qhmzZrKkSOH8ubNq2eeeUYnT568Z53Jzp8/r06dOikoKEj58uXTSy+9pJs3bzq3N2zYUFWrVk31uWXLllXz5s3vuO/IyEjlz59ft27dSrGtWbNmKlu2rNvH8t1336ljx44qXry47Ha7QkNDNXToUN24ccOlXfJn6vDhw/rLX/6iwMBAde3a9Z79gayLERVkSmFhYdqyZYtiYmJUqVKlO7b7z3/+oxdeeEGPPvqoevfuLUkKDw+XJO3du1f169dXUFCQRowYIT8/P3344Yd64okntH79etWpU0eSdPXqVdWvX18///yzevXqpRo1auj8+fNatmyZfv31V+XPnz/F6964cUNt2rTR9u3btXr1amcY+bPy5cvrjTfe0OjRo9W7d2/Vr19fklS3bl1nmwsXLqhFixZ65pln9Nxzz6lgwYKSpJkzZyogIEDDhg1TQECA1qxZo9GjRys+Pl7//Oc/nc//5JNP1KdPH9WtW1dDhgzRkSNH1Lp1a+XNm1ehoaH37OvExEQ1b95cderU0TvvvKPVq1fr3XffVXh4uPr16ydJSkpKUqtWrfTDDz+oX79+KleunJYuXarIyMh77r9WrVp65JFHNH/+/BTt582bpzx58jh/6ab1PfOE6Oho5ciRQ6NGjdKhQ4c0ZcoU+fn5ycfHR5cuXdLrr7+urVu3aubMmSpZsqRGjx7tfO64ceP02muvqVOnTnrhhRf022+/acqUKWrQoIF27tyZasD+s06dOqlEiRKKjo7W1q1b9f777+vSpUuaPXu2JKlbt2568cUXU/wMbNu2Tb/88oteffXVO+67W7dumj17tlauXKmnn37auf7s2bNas2aNxowZ4/axLFiwQNevX1e/fv2UL18+/fDDD5oyZYp+/fVXLViwwOX1b9++rebNm6tevXp655130mWEEA8RA2RC33zzjfH19TW+vr4mIiLCjBgxwqxcudIkJCSkaJsrVy4TGRmZYn3btm1N9uzZzeHDh53rTp8+bQIDA02DBg2c60aPHm0kmUWLFqXYR1JSkjHGmLVr1xpJZsGCBebKlSumYcOGJn/+/Gbnzp33PJZt27YZSWbGjBkptjVs2NBIMtOnT0+x7fr16ynW9enTx+TMmdPcvHnTGGNMQkKCKVCggKlWrZpxOBzOdh999JGRZBo2bOhcd/To0RR1REZGGknmjTfecHmd6tWrm5o1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aIoWLWqyZ89uihUrZiIjI8358+eNMa6XJ//RiBEjjCQzderUux7P0qVLTYUKFUy2bNlcLudt2LChqVixYqrP2bRpk3nsscdMjhw5TJEiRZyXaOtPl+UaY8y//vUvU7JkSWO3202tWrXMhg0bUlyWe6fLk3PlypXitZMvof2j3377zTz77LMmMDDQBAcHmx49ephNmzYZSWbu3Ll3Pf5kBw8eNJKMJLNx48ZU26TlPUvt8mRjjHn33XdN0aJFjd1uN48//rjZvn37HS9P/vN7OWPGDCPJbNu2LdW++O2331zWL1y40NSrV8/5/025cuXMgAEDzIEDB+7aB8n727dvn+nQoYMJDAw0efLkMQMHDjQ3btxI9Tlvv/22kZTi/6e0mD9/vpFkevfufcc2aTmWffv2mSZNmpiAgACTP39+8+KLL5rdu3en+TMF3InNmFTGrjM5m82mxYsXO6/cmTdvnrp27aq9e/emOHcbEBCgQoUKuazr0aOH4uLiUlw51KBBA9WoUUOTJk1yrpsxY4aGDBmSYlY7AGnJkiVq166dNm7cqMcff9zb5Ty0Jk+erKFDh+rYsWMprla6l6VLl6pt27basGGD84aDgJVkiVM/1atXV2JiomJjYx/oBzEiIsI5ByLZqlWrFBER8aAlApnen09/JiYmasqUKQoKCnLrdATcY4zRJ598ooYNG7odUiTp448/1iOPPKJ69eqlQ3XAg3togsrVq1ddrjA4evSodu3apbx586pMmTLq2rWrunfvrnfffVfVq1fXb7/9pm+//VZVqlRxnpfdt2+fEhISdPHiRV25csX5bbbJN+3q27evpk6dqhEjRqhXr15as2aN5s+fr+XLl2f04QKWM2jQIN24cUMRERFyOBxatGiRNm/erLfeeov5W+ng2rVrWrZsmdauXas9e/Zo6dKlbj0/+cKC5cuXa/Lkyfd19RmQIbx86sljks8r//mRPB8hISHBjB492pQoUcL4+fmZwoULm3bt2pmffvrJuY+wsLBU9/Hn16lWrZrJnj27eeSRR+55a3Agq/jss89MjRo1TFBQkMmePbupUKGCmTJlirfLemglzynKnTu3+fvf/+728yWZgIAA8/zzz5tbt26lQ4WAZzyUc1QAAMDDIcvcRwUAAGQ+BBUAAGBZmXoybVJSkk6fPq3AwEAmggEAkEkYY3TlyhUVKVLk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O6gcPXo0PeoAAABIgW9PBgAAlnVf3/VzN59++ul9FwMAAPBHbgeVS5cuuSzfunVLMTExiouL05NPPumxwgAAANwOKosXL06xLikpSf369eOSZQAA4FEemaPi4+OjYcOG6b333vPE7gAAACTdx4jKnRw+fFi3b9/21O4AALC0O92MLavciC2juB1Uhg0b5rJsjNGZM2e0fPlyRUZGeqwwAAAAt4PKzp07XZZ9fHwUEhKid999955XBAEAALjD7aCydu3a9KgDAAAgBbcn0964cUPXr193Lh8/flyTJk3SN99849HCAAAA3B5RadOmjdq3b6++ffsqLi5Ojz76qLJnz67z589r4sSJ6tevX3rUCQBAhuFbi63D7RGVH3/8UfXr15ckffnllypUqJCOHz+u2bNn6/333/d4gQAAIOtyO6hcv35dgYGBkqRvvvlG7du3l4+Pjx577DEdP37crX198MEHqlKlioKCghQUFKSIiAh9/fXX7pYEAAAeUm6f+ilVqpSWLFmidu3aaeXKlRo6dKgkKTY2VkFBQW7tq1ixYho/frxKly4tY4xmzZqlNm3aaOfOnapYsaK7pQEAYBmcPvIMt0dURo8ereHDh6tEiRKqU6eOIiIiJP0+ulK9enW39tWqVSv95S9/UenSpVWmTBmNGzdOAQEB2rp1q7tlAQCAh5DbIyodOnRQvXr1dObMGVWtWtW5vnHjxmrXrt19F5KYmKgFCxbo2rVrzvDzZw6HQw6Hw7kcHx9/368HAACs775uoV+oUCEVKlTIZd2jjz56XwXs2bNHERERunnzpgICArR48WJVqFAh1bbR0dEaO3bsfb0OAADIfDzypYQPomzZstq1a5e+//579evXT5GRkdq3b1+qbaOionT58mXn4+TJkxlcLQAAyEge+1LC+5U9e3aVKlVKklSzZk1t27ZNkydP1ocffpiird1ul91uz+gSAQCAl3h9ROXPkpKSXOahAACArMurIypRUVFq0aKFihcvritXrujzzz/XunXrtHLlSm+WBQAALMKrQSU2Nlbdu3fXmTNnFBwcrCpVqmjlypVq2rSpN8sCAAAW4dWg8sknn3jz5QEAgMVZbo4KAABAMoIKAACwLIIKAACwLIIKAACwLIIKAACwLIIKAACwLIIKAACwLIIKAACwLIIKAACwLIIKAACwLIIKAACwLIIKAACw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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "# 상대적으로 거래량이 미미한 1980 이전 데이터 필터링\n", + "stock_1980_2023_df = stock_df.filter('year >= 1980')\n", + "# the most volumn by year\n", + "volumn_sum_pandas = stock_1980_2023_df.groupBy('year', 'month')\\\n", + " .agg(_sum('volumn').alias('volumn_sum'))\\\n", + " .orderBy(col('year').asc(), col('month').asc())\\\n", + " .toPandas()\n", + "\n", + "plt.bar(volumn_sum_pandas['year'], volumn_sum_pandas['volumn_sum'])\n", + "plt.xlabel('year')\n", + "plt.ylabel('sum of volumn')\n", + "plt.title('Stock trading volume by year')\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 472 + }, + "id": "i5LUr-v22Jmm", + "outputId": "4b668f65-bc9a-46b5-b6ad-459c3c772499" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAHHCAYAAACRAnNyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA99klEQVR4nO3dd3xUVf7/8fckhAkhhRZ6CBh6ryLSRJosUpciIgRQ6SCwCGRVEFcMuIogsKKuUhaVInVlBUEISFNAQAKCdJAWKSHUCSTn94e/zNcxATIwydzA6/l4zOPhvXPm3s+dk8g75557r80YYwQAAGBBPt4uAAAA4HYIKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKgAAwLIIKoAHxMTEyGaz6csvv/R2Ken2xBNP6IknnnAuHz16VDabTTNnzvRaTZ6S0h8xMTHeLsVtr7/+umw2m86dO+ftUgBLIKggy9q9e7c6dOig8PBw+fv7q0iRImratKmmTJni0u6tt97SkiVLvFNkOpw6dUqvv/66du7c6e1SAMByCCrIkjZt2qSaNWtq165devHFFzV16lS98MIL8vHx0eTJk13aZoWgMnbsWK8HlfDwcF2/fl3dunXzah0A8EfZvF0AcC/GjRunkJAQbd26Vbly5XJ5Ly4uzjtFZZJr164pICDA49u12Wzy9/f3+HaBu7l69apy5szp7TJgUYyoIEs6dOiQKlSokCqkSFL+/Pmd/22z2XT16lXNmjVLNptNNptNPXr0cL6/Y8cOtWjRQsHBwQoMDFTjxo21ZcuWVNuMj4/X0KFDVbx4cdntdhUtWlTdu3e/4zwCh8Ohp59+WiEhIdq0aVOabWJiYlSrVi1JUs+ePZ01pswTeeKJJ1SxYkVt375dDRo0UEBAgP7+979LkpYuXaqWLVuqcOHCstvtioiI0D/+8Q8lJSWl2s9HH32kiIgI5ciRQ48++qi+++67VG3SmqPSo0cPBQYG6uTJk2rbtq0CAwMVGhqq4cOHp9rP+fPn1a1bNwUHBytXrlyKjIzUrl277jrvZdu2bbLZbJo1a1aq91auXCmbzaavvvrKuS69ffZnxYsXd+n7FH+eq5Myv2X+/PkaO3asihQpoqCgIHXo0EGXLl2Sw+HQkCFDlD9/fgUGBqpnz55yOByptjtnzhzVqFFDOXLkUJ48efTMM8/oxIkTd60zxblz59SpUycFBwcrb968eumll3Tjxg3n+w0bNlSVKlXS/GyZMmXUvHnz2247MjJS+fLl082bN1O916xZM5UpU8btY/nuu+/UsWNHFStWTHa7XWFhYRo6dKiuX7/u0i7lZ+rQoUP6y1/+oqCgIHXt2vWu3wceXoyoIEsKDw/X5s2bFRsbq4oVK9623X/+8x+98MILevTRR9W7d29JUkREhCRpz549ql+/voKDgzVixAj5+fnpww8/1BNPPKF169apdu3akqQrV66ofv36+vnnn9WrVy9Vr15d586d07Jly/Trr78qX758qfZ7/fp1tWnTRtu2bdPq1audYeTPypUrpzfeeEOjR49W7969Vb9+fUnS448/7mxz/vx5tWjRQs8884yee+45FShQQJI0c+ZMBQYGatiwYQoMDNSaNWs0evRoJSQk6J///Kfz85988on69Omjxx9/XEOGDNHhw4fVunVr5cmTR2FhYXf9rpOSktS8eXPVrl1b77zzjlavXq13331XERER6tevnyQpOTlZrVq10g8//KB+/fqpbNmyWrp0qSIjI++6/Zo1a+qRRx7R/PnzU7WfN2+ecufO7fxHN7195gnR0dHKkSOHRo0apYMHD2rKlCny8/OTj4+PLl68qNdff11btmzRzJkzVaJECY0ePdr52XHjxum1115Tp06d9MILL+i3337TlClT1KBBA+3YsSPNgP1nnTp1UvHixRUdHa0tW7bo/fff18WLFzV79mxJUrdu3fTiiy+m+h3YunWrfvnlF7366qu33Xa3bt00e/ZsrVy5Uk8//bRz/ZkzZ7RmzRqNGTPG7WNZsGCBrl27pn79+ilv3rz64YcfNGXKFP36669asGCBy/5v3bql5s2bq169enrnnXcyZIQQDxADZEHffPON8fX1Nb6+vqZOnTpmxIgRZuXKlSYxMTFV25w5c5rIyMhU69u2bWuyZ89uDh065Fx36tQpExQUZBo0aOBcN3r0aCPJLFq0KNU2kpOTjTHGrF271kgyCxYsMJcvXzYNGzY0+fLlMzt27LjrsWzdutVIMjNmzEj1XsOGDY0kM3369FTvXbt2LdW6Pn36mICAAHPjxg1jjDGJiYkmf/78pmrVqsbhcDjbffTRR0aSadiwoXPdkSNHUtURGRlpJJk33njDZT/VqlUzNWrUcC4vXLjQSDKTJk1yrktKSjJPPvnkbY/tj6Kiooyfn5+5cOGCc53D4TC5cuUyvXr1cq5Lb5+l9MfatWud68LDw9P8OWjYsKHL95Dy2YoVK7r8PHXp0sXYbDbTokULl8/XqVPHhIeHO5ePHj1qfH19zbhx41za7d6922TLli3V+j8bM2aMkWRat27tsr5///5Gktm1a5cxxpj4+Hjj7+9vRo4c6dJu8ODBJmfOnObKlSu33UdSUpIpWrSo6dy5s8v6iRMnGpvNZg4fPuz2saT18xgdHW1sNps5duyYc13Kz9SoUaPu9DUATpz6QZbUtGlTbd68Wa1bt9auXbv09ttvq3nz5ipSpIiWLVt2188nJSXpm2++Udu2bfXII4841xcqVEjPPvusNmzYoISEBEnSwoULVaVKFbVr1y7Vdmw2m8vypUuX1KxZM+3bt08xMTGqWrXq/R2oJLvdrp49e6ZanyNHDud/X758WefOnVP9+vV17do17du3T9Lvp1Xi4uLUt29fZc+e3dm+R48eCgkJSXcNffv2dVmuX7++Dh8+7FxesWKF/Pz89OKLLzrX+fj4aMCAAenafufOnXXz5k0tWrTIue6bb75RfHy8OnfuLMm9PvOE7t27y8/Pz7lcu3ZtGWPUq1cvl3a1a9fWiRMndOvWLUnSokWLlJycrE6dOuncuXPOV8GCBVWqVCmtXbs2Xfv/83c3aNAgSdL//vc/SVJISIjatGmjL774QsYYSb9/R/PmzVPbtm3vOOfDx8dHXbt21bJly3T58mXn+s8++0yPP/64SpQo4fax/PHn8erVqzp37pwef/xxGWO0Y8eOVDWkjMYBd/PABJX169erVatWKly4sGw2m9tXedy4cUM9evRQpUqVlC1bNrVt2zbNdjExMapevbrsdrtKliz5QNxzIquqVauWFi1apIsXL+qHH35QVFSULl++rA4dOmjv3r13/Oxvv/2ma9eupToXL/1+OiY5Odl5Dv7QoUN3PL30R0OGDNHWrVu1evVqVahQwf2DSkORIkVcQkaKPXv2qF27dgoJCVFwcLBCQ0P13HPPSfo9MEnSsWPHJEmlSpVy+ayfn5/LP/Z34u/vr9DQUJd1uXPn1sWLF53Lx44dU6FChVIN4ZcsWTJd+6hSpYrKli2refPmOdfNmzdP+fLl05NPPinJvT7zhGLFirkspwS7P58uCwkJUXJysvM7P3DggIwxKlWqlEJDQ11eP//8c7one/+5zyIiIuTj46OjR48613Xv3l3Hjx93zjlavXq1zp49m64rt7p3767r169r8eLFkqT9+/dr+/btLp9151iOHz+uHj16KE+ePM65TA0bNpT0fz+PKbJly6aiRYum63sAHpg5KlevXlWVKlXUq1cvtW/f3u3PJyUlKUeOHBo8eLAWLlyYZpsjR46oZcuW6tu3rz777DN9++23euGFF1SoUKE7TlxDxsqePbtq1aqlWrVqqXTp0urZs6cWLFjgcp49s7Rp00Zz587V+PHjNXv2bPn43P/fAn/8SzVFfHy8GjZsqODgYL3xxhuKiIiQv7+/fvzxR40cOVLJycn3vd8Uvr6+HtvWnXTu3Fnjxo3TuXPnFBQUpGXLlqlLly7Kls0z/5v68+hXiqSkpDSP8XbHfbv1KaMaycnJstls+vrrr9NsGxgYmN6SXaRVf/PmzVWgQAHNmTNHDRo00Jw5c1SwYEE1adLkrtsrX768atSooTlz5qh79+6aM2eOsmfPrk6dOjnbpPdYkpKS1LRpU124cEEjR45U2bJllTNnTp08eVI9evRI9fNot9s98ruBh8MDE1RatGihFi1a3PZ9h8OhV155RV988YXi4+NVsWJFTZgwwTnbP2fOnPrggw8kSRs3blR8fHyqbUyfPl0lSpTQu+++K+n3v+I2bNig9957j6BiETVr1pQknT592rkurf/Bh4aGKiAgQPv370/13r59++Tj4+P8yzkiIkKxsbHp2n/btm3VrFkz9ejRQ0FBQc6fqTu53T+gdxITE6Pz589r0aJFatCggXP9kSNHXNqFh4dL+v0v45SRCUm6efOmjhw5cturRtwVHh6utWvXprp0+uDBg+neRufOnTV27FgtXLhQBQoUUEJCgp555hnn++70WVpy586d5u/1sWPH0j26lB4REREyxqhEiRIqXbr0PW/nwIEDzlMw0u/fZXJysooXL+5c5+vrq2effVYzZ87UhAkTtGTJEr344ovpDpfdu3fXsGHDdPr0aX3++edq2bKlcufO7fax7N69W7/88otmzZql7t27O9evWrXKjSMG0vbQRNqBAwdq8+bNmjt3rn766Sd17NhRTz31lA4cOJDubWzevDnVXyrNmzfX5s2bPV0u7mLt2rXOv2D/KOX8/R9PD+TMmTPVP1C+vr5q1qyZli5d6jKUfvbsWX3++eeqV6+egoODJUl//etftWvXLucQ+R+lVUP37t31/vvva/r06Ro5cuRdjyVlLkFa/4jeTso/RH/cf2Jiov71r3+5tKtZs6ZCQ0M1ffp0JSYmOtfPnDnTrf3dTfPmzXXz5k19/PHHznXJycmaNm1aurdRrlw5VapUSfPmzdO8efNUqFAhlxDmTp+lJSIiQlu2bHH5Hr766iuPni6SpPbt28vX11djx45N9fNhjNH58+fTtZ0/f3cpd1z+8x9k3bp108WLF9WnTx9duXLFefovPbp06SKbzaaXXnpJhw8fTvXZ9B5LWj+PxphUN18E7sUDM6JyJ8ePH9eMGTN0/PhxFS5cWJI0fPhwrVixQjNmzNBbb72Vru2cOXPGeWloipS//K5fv57mED0yxqBBg3Tt2jW1a9dOZcuWVWJiojZt2qR58+apePHiLpNPa9SoodWrV2vixIkqXLiwSpQoodq1a+vNN9/UqlWrVK9ePfXv31/ZsmXThx9+KIfDobffftv5+ZdffllffvmlOnbsqF69eqlGjRq6cOGCli1bpunTp6c5KjFw4EAlJCTolVdeUUhIiPPeJ2mJiIhQrly5NH36dAUFBSlnzpyqXbu2y1/Tf/b4448rd+7cioyM1ODBg2Wz2fSf//wn1T8mfn5+evPNN9WnTx89+eST6ty5s44cOaIZM2Z4dBShbdu2evTRR/W3v/1NBw8eVNmyZbVs2TJduHBBUvpHjTp37qzRo0fL399fzz//fKrTA+nts7S88MIL+vLLL/XUU0+pU6dOOnTokObMmeO8XN1TIiIi9OabbyoqKkpHjx5V27ZtFRQUpCNHjmjx4sXq3bu3hg8fftftHDlyRK1bt9ZTTz2lzZs3a86cOXr22WdT/bxVq1ZNFStW1IIFC1SuXDlVr1493bWGhobqqaee0oIFC5QrVy61bNnyno6lbNmyioiI0PDhw3Xy5EkFBwdr4cKFLvOYgHuW2ZcZZQZJZvHixc7lr776ykgyOXPmdHlly5bNdOrUKdXnIyMjTZs2bVKtL1WqlHnrrbdc1i1fvtxISvPSPGScr7/+2vTq1cuULVvWBAYGmuzZs5uSJUuaQYMGmbNnz7q03bdvn2nQoIHJkSOHkeRyieqPP/5omjdvbgIDA01AQIBp1KiR2bRpU6r9nT9/3gwcONAUKVLEZM+e3RQtWtRERkaac+fOGWNcL0/+oxEjRhhJZurUqXc8nqVLl5ry5cubbNmyuVzO27BhQ1OhQoU0P7Nx40bz2GOPmRw5cpjChQs7L9HWny7LNcaYf/3rX6ZEiRLGbrebmjVrmvXr16e6LPd2lyfnzJkz1b5TLqH9o99++808++yzJigoyISEhJgePXqYjRs3Gklm7ty5dzz+FAcOHDCSjCSzYcOGNNukp8/SujzZGGPeffddU6RIEWO3203dunXNtm3bbnt58p/7csaMGUaS2bp1a5rfxW+//eayfuHChaZevXrO/9+ULVvWDBgwwOzfv/+O30HK9vbu3Ws6dOhggoKCTO7cuc3AgQPN9evX0/zM22+/bSSl+v9TesyfP99IMr17975tm/Qcy969e02TJk1MYGCgyZcvn3nxxRfNrl270v0zBdyOzZg0xq6zOJvNpsWLFzuv3Jk3b566du2qPXv2pDp3GxgYqIIFC7qs69Gjh+Lj41NdOdSgQQNVr15dkyZNcq6bMWOGhgwZkmpWOwBpyZIlateunTZs2KC6det6u5wH1uTJkzV06FAdPXo01dVKd7N06VK1bdtW69evd95wELCSh+LUT7Vq1ZSUlKS4uLj7+kWsU6eOcw5EilWrVqlOnTr3WyKQ5f359GdSUpKmTJmi4OBgt05HwD3GGH3yySdq2LCh2yFFkj7++GM98sgjqlevXgZUB9y/ByaoXLlyxeUKgyNHjmjnzp3KkyePSpcura5du6p79+569913Va1aNf3222/69ttvVblyZed52b179yoxMVEXLlzQ5cuXnU+zTblpV9++fTV16lSNGDFCvXr10po1azR//nwtX748sw8XsJxBgwbp+vXrqlOnjhwOhxYtWqRNmzbprbfeYv5WBrh69aqWLVumtWvXavfu3Vq6dKlbn0+5sGD58uWaPHnyPV19BmQKL5968piU88p/fqXMR0hMTDSjR482xYsXN35+fqZQoUKmXbt25qeffnJuIzw8PM1t/Hk/VatWNdmzZzePPPLIXW8NDjwsPvvsM1O9enUTHBxssmfPbsqXL2+mTJni7bIeWClzinLlymX+/ve/u/15SSYwMNA8//zz5ubNmxlQIeAZD+QcFQAA8GB4aO6jAgAAsh6CCgAAsKwsPZk2OTlZp06dUlBQEBPBAADIIowxunz5sgoX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sKyHKqisX79erVq1UuHChWWz2bRkyRKX98+ePasePXqocOHCCggI0FNPPaUDBw64tDlz5oy6deumggULKmfOnKpevboWLlzo0ubChQvq2rWrgoODlStXLj3//PO6cuVKRh/eA8ETfXTo0CG1a9dOoaGhCg4OVqdOnVLd/Zg+unfR0dGqVauWgoKClD9/frVt21b79+93aXPjxg0NGDBAefPmVWBgoP7617+m6oPjx4+rZcuWCggIUP78+fXyyy/r1q1bLm1iYmJUvXp12e12lSxZUjNnzszow3sgeKqPBg8erBo1ashut6tq1app7uunn35S/fr15e/vr7CwML399tsZdVgPHE/0065du9SlSxeFhYUpR44cKleunCZPnpxqX1n5d+mhCipXr15VlSpVNG3atFTvGWPUtm1bHT58WEuXLtWOHTsUHh6uJk2a6OrVq8523bt31/79+7Vs2TLt3r1b7du3V6dOnbRjxw5nm65du2rPnj1atWqVvvrqK61fv169e/fOlGPM6u63j65evapmzZrJZrNpzZo12rhxoxITE9WqVSslJyc7t0Uf3bt169ZpwIAB2rJli1atWqWbN2+qWbNmLr8nQ4cO1X//+18tWLBA69at06lTp9S+fXvn+0lJSWrZsqUSExO1adMmzZo1SzNnztTo0aOdbY4cOaKWLVuqUaNG2rlzp4YMGaIXXnhBK1euzNTjzYo80UcpevXqpc6dO6e5n4SEBDVr1kzh4eHavn27/vnPf+r111/XRx99lGHH9iDxRD9t375d+fPn15w5c7Rnzx698sorioqK0tSpU51tsvzvkiceLpgVSTKLFy92Lu/fv99IMrGxsc51SUlJJjQ01Hz88cfOdTlz5jSzZ8922VaePHmcbfbu3Wskma1btzrf//rrr43NZjMnT57MoKN5MN1LH61cudL4+PiYS5cuOdvEx8cbm81mVq1aZYyhjzwtLi7OSDLr1q0zxvz+ffv5+ZkFCxY42/z8889Gktm8ebMxxpj//e9/xsfHx5w5c8bZ5oMPPjDBwcHG4XAYY4wZMWKEqVChgsu+OnfubJo3b57Rh/TAuZc++qMxY8aYKlWqpFr/r3/9y+TOndvZZ8YYM3LkSFOmTBnPH8RD4H77KUX//v1No0aNnMtZ/XfpoRpRuROHwyFJ8vf3d67z8fGR3W7Xhg0bnOsef/xxzZs3TxcuXFBycrLmzp2rGzdu6IknnpAkbd68Wbly5VLNmjWdn2nSpIl8fHz0/fffZ87BPKDS00cOh0M2m83lJkj+/v7y8fFxtqGPPOvSpUuSpDx58kj6/S+8mzdvqkmTJs42ZcuWVbFixbR582ZJv/dBpUqVXO5A3bx5cyUkJGjPnj3ONn/cRkqblG0g/e6lj9Jj8+bNatCggbJnz+5c17x5c+3fv18XL170UPUPD0/106VLl5zbkLL+7xJB5f9L6fyoqChdvHhRiYmJmjBhgn799VedPn3a2W7+/Pm6efOm8ubNK7vdrj59+mjx4sUqWbKkpN/nsOTPn99l29myZVOePHl05syZTD2mB016+uixxx5Tzpw5NXLkSF27dk1Xr17V8OHDlZSU5GxDH3lOcnKyhgwZorp166pixYqSfv9+s2fPnuqBoQUKFHB+v2fOnEn1mIyU5bu1SUhI0PXr1zPicB5I99pH6ZGefkT6eKqfNm3apHnz5rmcys7qv0sElf/Pz89PixYt0i+//KI8efIoICBAa9euVYsWLeTj839f02uvvab4+HitXr1a27Zt07Bhw9SpUyft3r3bi9U/HNLTR6GhoVqwYIH++9//KjAwUCEhIYqPj1f16tVd+hGeMWDAAMXGxmru3LneLgW3QR9lDZ7op9jYWLVp00ZjxoxRs2bNPFidd1niWT9WUaNGDe3cuVOXLl1SYmKiQkNDVbt2becpgkOHDmnq1KmKjY1VhQoVJElVqlTRd999p2nTpmn69OkqWLCg4uLiXLZ769YtXbhwQQULFsz0Y3rQ3K2PJKlZs2Y6dOiQzp07p2zZsilXrlwqWLCgHnnkEUmijzxk4MCBzonIRYsWda4vWLCgEhMTFR8f7/KX4NmzZ53fb8GCBfXDDz+4bC/lSoY/tvnzVShnz55VcHCwcuTIkRGH9MC5nz5Kj9v1Ucp7SB9P9NPevXvVuHFj9e7dW6+++qrLe1n9d4k/MdMQEhKi0NBQHThwQNu2bVObNm0kSdeuXZOkVH+Z+/r6Oq8oqVOnjuLj47V9+3bn+2vWrFFycrJq166dSUfw4LtdH/1Rvnz5lCtXLq1Zs0ZxcXFq3bq1JProfhljNHDgQC1evFhr1qxRiRIlXN6vUaOG/Pz89O233zrX7d+/X8ePH1edOnUk/d4Hu3fvdgmMq1atUnBwsMqXL+9s88dtpLRJ2QZuzxN9lB516tTR+vXrdfPmTee6VatWqUyZMsqdO/f9H8gDzlP9tGfPHjVq1EiRkZEaN25cqv1k+d8lL0/mzVSXL182O3bsMDt27DCSzMSJE82OHTvMsWPHjDHGzJ8/36xdu9YcOnTILFmyxISHh5v27ds7P5+YmGhKlixp6tevb77//ntz8OBB88477xibzWaWL1/ubPfUU0+ZatWqme+//95s2LDBlCpVynTp0iXTjzcrut8+MsaYTz/91GzevNkcPHjQ/Oc//zF58uQxw4YNc2lDH927fv36mZCQEBMTE2NOnz7tfF27ds3Zpm/fvqZYsWJmzZo1Ztu2baZOnTqmTp06zvdv3bplKlasaJo1a2Z27txpVqxYYUJDQ01UVJSzzeHDh01AQIB5+eWXzc8//2ymTZtmfH19zYoVKzL1eLMiT/SRMcYcOHDA7Nixw/Tp08eULl3a+buZcpVPfHy8KVCggOnWrZuJjY01c+fONQEBAebDDz/M1OPNqjzRT7t37zahoaHmueeec9lGXFycs01W/116qILK2rVrjaRUr8jISGOMMZMnTzZFixY1fn5+plixYubVV191uezOGGN++eUX0759e5M/f34TEBBgKleunOpy5fPnz5suXbqYwMBAExwcbHr27GkuX76cWYeZpXmij0aOHGkKFChg/Pz8TKlSpcy7775rkpOTXdrQR/curf6RZGbMmOFsc/36ddO/f3+TO3duExAQYNq1a2dOnz7tsp2jR4+aFi1amBw5cph8+fKZv/3tb+bmzZsubdauXWuqVq1qsmfPbh555BGXfeD2PNVHDRs2THM7R44ccbbZtWuXqVevnrHb7aZIkSJm/PjxmXSUWZ8n+mnMmDFpbiM8PNxlX1n5d8lmjDEZN14DAABw75ijAgAALIugAgAALIugAgAALIugAgAALIugAgAALIugAgAALIugAgAALIugAgAALIugAgAALIugAuCBk5SU5HxQKICsjaACIEPNnj1befPmlcPhcFnftm1bdevWTZK0dOlSVa9eXf7+/nrkkUc0duxY3bp1y9l24sSJqlSpknLmzKmwsDD1799fV65ccb4/c+ZM5cqVS8uWLVP58uVlt9t1/PjxzDlAABmKoAIgQ3Xs2FFJSUlatmyZc11cXJyWL1+uXr166bvvvlP37t310ksvae/evfrwww81c+ZMl8fV+/j46P3339eePXs0a9YsrVmzRiNGjHDZz7Vr1zRhwgT9+9//1p49e5Q/f/5MO0YAGYeHEgLIcP3799fRo0f1v//9T9LvIyTTpk3TwYMH1bRpUzVu3FhRUVHO9nPmzNGIESN06tSpNLf35Zdfqm/fvjp37pyk30dUevbsqZ07d6pKlSoZf0AAMg1BBUCG27Fjh2rVqqVjx46pSJEiqly5sjp27KjXXntNoaGhunLlinx9fZ3tk5KSdOPGDV29elUBAQFavXq1oqOjtW/fPiUkJOjWrVsu78+cOVN9+vTRjRs3ZLPZvHikADwtm7cLAPDgq1atmqpUqaLZs2erWbNm2rNnj5YvXy5JunLlisaOHav27dun+py/v7+OHj2qp59+Wv369dO4ceOUJ08ebdiwQc8//7wSExMVEBAgScqRIwchBXgAEVQAZIoXXnhBkyZN0smTJ9WkSROFhYVJkqpXr679+/erZMmSaX5u+/btSk5O1rvvvisfn9+n1c2fPz/T6gbgXQQVAJni2Wef1fDhw/Xxxx9r9uzZzvWjR4/W008/rWLFiqlDhw7y8fHRrl27FBsbqzfffFMlS5bUzZs3NWXKFLVq1UobN27U9OnTvXgkADITV/0AyBQhISH661//qsDAQLVt29a5vnnz5vrqq6/0zTffqFatWnrsscf03nvvKTw8XJJUpUoVTZw4URMmTFDFihX12WefKTo62ktHASCzMZkWQKZp3LixKlSooPfff9/bpQDIIggqADLcxYsXFRMTow4dOmjv3r0qU6aMt0sCkEUwRwVAhqtWrZouXryoCRMmEFIAuIURFQAAYFlMpgUAAJZFUAEAAJZFUAEAAJZFUAEAAJZFUAEAAJZFUAEAAJZFUAEAAJZFUAEAAJZFUAEAAJb1/wBLD8ABwZliHwAAAABJRU5ErkJggg==\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "# 가장 오랫동안 거래된(거래일이 많은) 종목 정렬\n", + "stock_df.groupBy('ticker')\\\n", + " .agg(count('*').alias('ticker_count'))\\\n", + " .orderBy(col('ticker_count').desc())\\\n", + " .show(20)\n", + "\n", + "ticker_set = {'GT', 'TXN', 'DIOD', 'KLIC', 'MSEX', 'OTTR'}" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "nYJdrbdd7oCQ", + "outputId": "0117c6e8-5184-4a63-ccac-0f7d2145a676" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "+------+------------+\n", + "|ticker|ticker_count|\n", + "+------+------------+\n", + "| GT| 13356|\n", + "| TXN| 12744|\n", + "| DIOD| 12564|\n", + "| KLIC| 12564|\n", + "| MSEX| 12564|\n", + "| OTTR| 12564|\n", + "| SGC| 12564|\n", + "| VLGEA| 12564|\n", + "| PHI| 12514|\n", + "| APOG| 12514|\n", + "| ALCO| 12514|\n", + "| MAT| 11724|\n", + "| HELE| 11710|\n", + "| TRNS| 11354|\n", + "| TSRI| 11256|\n", + "| WDC| 11125|\n", + "| FARM| 10778|\n", + "| PATK| 10778|\n", + "| PCAR| 10778|\n", + "| WABC| 10778|\n", + "+------+------------+\n", + "only showing top 20 rows\n", + "\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# 주가 상승일이 많은 종목 정렬\n", + "stock_df.filter('close > open')\\\n", + " .groupBy('ticker')\\\n", + " .agg(count('*').alias('ticker_count'))\\\n", + " .orderBy(col('ticker_count').desc())\\\n", + " .show(20)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ouU5G6oTAEj1", + "outputId": "783e8f74-ea5a-4fff-d0e5-acddc80d8b90" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "+------+------------+\n", + "|ticker|ticker_count|\n", + "+------+------------+\n", + "| OTTR| 8262|\n", + "| KLIC| 7824|\n", + "| SGC| 7541|\n", + "| DIOD| 7514|\n", + "| WABC| 6733|\n", + "| LANC| 6601|\n", + "| NTRS| 6581|\n", + "| MOG-A| 6516|\n", + "| SIGI| 6511|\n", + "| CINF| 6510|\n", + "| HELE| 6510|\n", + "| WEN| 6470|\n", + "| NDSN| 6440|\n", + "| ZION| 6431|\n", + "| HBAN| 6412|\n", + "| FITB| 6398|\n", + "| KELYA| 6366|\n", + "| SMTC| 6358|\n", + "| MGEE| 6351|\n", + "| SEIC| 6283|\n", + "+------+------------+\n", + "only showing top 20 rows\n", + "\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# prompt: Stocks with a high share price increase rate per ticker over the entire trading day\n", + "stock_df.groupBy('ticker')\\\n", + " .agg(\n", + " count_if(col('close') > col('open')).alias('rise_count'),\n", + " count('*').alias('trade_date_count'))\\\n", + " .withColumn('rise_rate', col('rise_count') / col('trade_date_count'))\\\n", + " .orderBy(col('rise_rate').desc())\\\n", + " .show(30)\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "0lN7TLG3KOra", + "outputId": "27bc7273-9b21-487a-815c-4507f4378606" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "+------+----------+----------------+------------------+\n", + "|ticker|rise_count|trade_date_count| rise_rate|\n", + "+------+----------+----------------+------------------+\n", + "| OTTR| 8262| 12564|0.6575931232091691|\n", + "| WABC| 6733| 10778|0.6246984598255706|\n", + "| KLIC| 7824| 12564|0.6227316141356256|\n", + "| LANC| 6601| 10778|0.6124512896641306|\n", + "| NTRS| 6581| 10778|0.6105956578214882|\n", + "| MOG-A| 6516| 10727|0.6074391721823437|\n", + "| SIGI| 6511| 10778|0.6041009463722398|\n", + "| CINF| 6510| 10778|0.6040081647801077|\n", + "| WEN| 6470| 10743|0.6022526296192869|\n", + "| SGC| 7541| 12564|0.6002069404648201|\n", + "| DIOD| 7514| 12564|0.5980579433301496|\n", + "| NDSN| 6440| 10777|0.5975688967245059|\n", + "| SEIC| 6283| 10520|0.5972433460076045|\n", + "| ZION| 6431| 10778|0.5966784190016701|\n", + "| HBAN| 6412| 10778|0.5949155687511598|\n", + "| FITB| 6398| 10778|0.5936166264613101|\n", + "| KELYA| 6366| 10778|0.5906476155130822|\n", + "| SMTC| 6358| 10778|0.5899053627760252|\n", + "| MGEE| 6351| 10778|0.5892558916311004|\n", + "| GNTX| 6040| 10331|0.5846481463556287|\n", + "| UHS| 6079| 10447|0.5818895376663157|\n", + "| WAFD| 5874| 10108|0.5811238622872972|\n", + "| CMCSA| 6233| 10778|0.5783076637595101|\n", + "| POWL| 6216| 10778|0.5767303766932641|\n", + "| AGYS| 6194| 10778|0.5746891816663574|\n", + "| KBAL| 6182| 10778|0.5735758025607719|\n", + "| JBHT| 5642| 9845| 0.573082783138649|\n", + "| CTAS| 5677| 9911|0.5727979013217637|\n", + "| GPS| 6147| 10778|0.5703284468361477|\n", + "| PAYX| 5622| 9906|0.5675348273773471|\n", + "+------+----------+----------------+------------------+\n", + "only showing top 30 rows\n", + "\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# 우리가 잘 하는 애플, 마이크로소프느는 어떨까?\n", + "stock_df.filter('ticker IN (\"AAPL\", \"MSFT\", \"MVRS\", \"FB\", \"NVDA\", \"TESLA\", \"GOOGL\", \"GOOL\")')\\\n", + " .groupBy('ticker')\\\n", + " .agg(\n", + " count_if(col('close') > col('open')).alias('rise_count'),\n", + " count('*').alias('trade_date_count'))\\\n", + " .withColumn('rise_rate', col('rise_count') / col('trade_date_count'))\\\n", + " .orderBy(col('rise_rate').desc())\\\n", + " .show(30)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "0xqKgnYTT5_5", + "outputId": "120313aa-8114-4327-e739-6e6bcd6672e7" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "+------+----------+----------------+------------------+\n", + "|ticker|rise_count|trade_date_count| rise_rate|\n", + "+------+----------+----------------+------------------+\n", + "| MSFT| 4587| 9264|0.4951424870466321|\n", + "| NVDA| 2970| 6013|0.4939298187260935|\n", + "| AAPL| 4807| 10555|0.4554239696826149|\n", + "+------+----------+----------------+------------------+\n", + "\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# average days of close > open\n", + "stock_df.filter('close > open')\\\n", + " .groupBy('ticker')\\\n", + " .agg(count('*').alias('ticker_count'))\\\n", + " .agg(avg('ticker_count').alias('avg_ticker_count'))\\\n", + " .show()\n", + "\n", + "# 50, 75, 95, 99 percential of close > open\n", + "\n", + "# 50 percentail of close > open\n", + "print(stock_df.filter('close > open')\\\n", + " .groupBy('ticker')\\\n", + " .agg(count('*').alias('ticker_count'))\\\n", + " .approxQuantile('ticker_count', [0.5], 0.05))\n", + "\n", + "# 75 percentail of close > open\n", + "print(stock_df.filter('close > open')\\\n", + " .groupBy('ticker')\\\n", + " .agg(count('*').alias('ticker_count'))\\\n", + " .approxQuantile('ticker_count', [0.75], 0.05))\n", + "\n", + "# 90 percentail of close > open\n", + "print(stock_df.filter('close > open')\\\n", + " .groupBy('ticker')\\\n", + " .agg(count('*').alias('ticker_count'))\\\n", + " .approxQuantile('ticker_count', [0.90], 0.05))\n", + "\n", + "# 95 percentail of close > open\n", + "print(stock_df.filter('close > open')\\\n", + " .groupBy('ticker')\\\n", + " .agg(count('*').alias('ticker_count'))\\\n", + " .approxQuantile('ticker_count', [0.95], 0.05))\n", + "\n", + "# 99 percentail of close > open\n", + "print(stock_df.filter('close > open')\\\n", + " .groupBy('ticker')\\\n", + " .agg(count('*').alias('ticker_count'))\\\n", + " .approxQuantile('ticker_count', [0.99], 0.05))" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "wDrzkVifAtal", + "outputId": "c125ba9b-018d-435a-a7ac-0f15d1f1d456" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "+-----------------+\n", + "| avg_ticker_count|\n", + "+-----------------+\n", + "|2488.356638418079|\n", + "+-----------------+\n", + "\n", + "[2197.0]\n", + "[3156.0]\n", + "[3924.0]\n", + "[8262.0]\n", + "[8262.0]\n" + ] + } + ] + } + ] +} \ No newline at end of file