diff --git a/poetry.lock b/poetry.lock index 6e9be89..0392c3f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3321,14 +3321,14 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, [[package]] name = "tushare" -version = "1.4.16" +version = "1.4.17" description = "A utility for crawling historical and Real-time Quotes data of China stocks" optional = false python-versions = "*" groups = ["main"] files = [ - {file = "tushare-1.4.16-py3-none-any.whl", hash = "sha256:43ae9bd0a356b8eb16a781b096c4ba849eb6ff7854c9fce8aadc01e0a487e196"}, - {file = "tushare-1.4.16.tar.gz", hash = "sha256:20b6b9a1841bf730da3c27e68aa08a4fe4c4636a7fe6308903b46c9622d4467c"}, + {file = "tushare-1.4.17-py3-none-any.whl", hash = "sha256:a367389cbc50098f49a397263284ec424877b72e4776cb2ba59d4b0dd6f2bc37"}, + {file = "tushare-1.4.17.tar.gz", hash = "sha256:e73c471ec96261b70937a66daa7942ad6372a86a37218468980c61dc8bace323"}, ] [package.dependencies] diff --git a/财报筛选/loader.py b/财报筛选/loader.py index 1853cf5..5953ea1 100644 --- a/财报筛选/loader.py +++ b/财报筛选/loader.py @@ -2,7 +2,8 @@ import os.path import pandas as pd -finance_root = "/Users/lanyuanxiaoyao/SynologyDrive/data/Tushare" +# finance_root = "/Users/lanyuanxiaoyao/SynologyDrive/data/Tushare" +finance_root = "C:\\Users\\lanyuanxiaoyao\\Documents\\Tushare" def load_balance_sheet(): diff --git a/财报筛选/金字塔选股.ipynb b/财报筛选/金字塔选股.ipynb index 0bd1be2..bbcd4a4 100644 --- a/财报筛选/金字塔选股.ipynb +++ b/财报筛选/金字塔选股.ipynb @@ -6,127 +6,31 @@ "metadata": { "collapsed": true, "ExecuteTime": { - "end_time": "2025-01-17T02:07:55.001963Z", - "start_time": "2025-01-17T02:07:54.772694Z" + "end_time": "2025-01-19T16:42:26.631868Z", + "start_time": "2025-01-19T16:42:26.628635Z" } }, "source": [ + "import numpy as np\n", "import pandas as pd\n", "import tushare as ts\n", "\n", "ts_pro = ts.pro_api(token=\"64ebff4fa679167600b905ee45dd88e76f3963c0ff39157f3f085f0e\")" ], "outputs": [], - "execution_count": 2 + "execution_count": 459 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-01-17T08:18:12.685428Z", - "start_time": "2025-01-17T08:18:12.676949Z" - } - }, - "cell_type": "code", - "source": [ - "df = pd.DataFrame([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]])\n", - "df.loc[df[0] > 2, 2] += 100\n", - "df" - ], - "id": "e19fd115ed8cb631", - "outputs": [ - { - "data": { - "text/plain": [ - " 0 1 2 3 4\n", - "0 1 2 3 4 5\n", - "1 6 7 108 9 10\n", - "2 11 12 113 14 15\n", - "3 16 17 118 19 20" - ], - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
01234
012345
167108910
211121131415
316171181920
\n", - "
" - ] - }, - "execution_count": 86, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 86 - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-17T10:11:56.563929Z", - "start_time": "2025-01-17T10:11:52.872684Z" + "end_time": "2025-01-19T16:42:27.857016Z", + "start_time": "2025-01-19T16:42:26.639161Z" } }, "cell_type": "code", "source": [ "import loader as loader\n", "\n", - "# 加载股票信息\n", - "stock_df = pd.read_csv(\"../材料/股票基础信息.csv\")\n", "# 加载财报信息\n", "source_finance_df = loader.load_finance()\n", "finance_df = pd.DataFrame()\n", @@ -169,11 +73,11 @@ " \"n_cashflow_act\",\n", "]]\n", "finance_df[\"score\"] = 0\n", - "finance_df = finance_df.sort_values(by=[\"code\", \"year\"], ascending=True)" + "finance_df = finance_df.sort_values(by=[\"code\", \"year\"], ascending=True).reset_index(drop=True)" ], "id": "68b2debc14502fd5", "outputs": [], - "execution_count": 148 + "execution_count": 460 }, { "metadata": {}, @@ -184,15 +88,15 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-01-17T10:11:57.531470Z", - "start_time": "2025-01-17T10:11:57.287352Z" + "end_time": "2025-01-19T16:42:27.931899Z", + "start_time": "2025-01-19T16:42:27.868963Z" } }, "cell_type": "code", "source": "finance_df = finance_df.groupby(\"code\").filter(lambda x: len(x) > 6)", "id": "4293bd93ea8f9ed", "outputs": [], - "execution_count": 149 + "execution_count": 461 }, { "metadata": {}, @@ -214,8 +118,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-01-17T10:12:05.859920Z", - "start_time": "2025-01-17T10:12:00.853021Z" + "end_time": "2025-01-19T16:42:29.192712Z", + "start_time": "2025-01-19T16:42:27.946033Z" } }, "cell_type": "code", @@ -224,17 +128,22 @@ "finance_df[\"roe\"] = finance_df[\"net_income\"] / (\n", " (finance_df[\"prev_total_stockholder_interest\"] + finance_df[\"total_stockholder_interest\"]) / 2)\n", "finance_df[\"average_roe\"] = finance_df.groupby(\"code\")[\"roe\"].rolling(window=5).mean().reset_index(0, drop=True)\n", - "finance_df.loc[finance_df[\"average_roe\"] >= 0.35, \"score\"] += 550\n", - "finance_df.loc[(finance_df[\"average_roe\"] >= 0.30) & (finance_df[\"average_roe\"] < 0.35), \"score\"] += 500\n", - "finance_df.loc[(finance_df[\"average_roe\"] >= 0.25) & (finance_df[\"average_roe\"] < 0.30), \"score\"] += 450\n", - "finance_df.loc[(finance_df[\"average_roe\"] >= 0.20) & (finance_df[\"average_roe\"] < 0.25), \"score\"] += 400\n", - "finance_df.loc[(finance_df[\"average_roe\"] >= 0.15) & (finance_df[\"average_roe\"] < 0.20), \"score\"] += 300\n", - "finance_df.loc[(finance_df[\"average_roe\"] >= 0.10) & (finance_df[\"average_roe\"] < 0.15), \"score\"] += 250\n", - "finance_df[\"score\"] = finance_df.groupby(\"code\").apply(\n", - " lambda x: x[\"score\"].mask(x[\"average_roe\"].rolling(window=5).apply(lambda y: (y < 0).any(), raw=False) > 0, 0)\n", - ").reset_index(drop=True)\n", + "finance_df[\"score_roe\"] = 0\n", + "finance_df.loc[finance_df[\"average_roe\"] >= 0.35, \"score_roe\"] += 550\n", + "finance_df.loc[(finance_df[\"average_roe\"] >= 0.30) & (finance_df[\"average_roe\"] < 0.35), \"score_roe\"] = 500\n", + "finance_df.loc[(finance_df[\"average_roe\"] >= 0.25) & (finance_df[\"average_roe\"] < 0.30), \"score_roe\"] = 450\n", + "finance_df.loc[(finance_df[\"average_roe\"] >= 0.20) & (finance_df[\"average_roe\"] < 0.25), \"score_roe\"] = 400\n", + "finance_df.loc[(finance_df[\"average_roe\"] >= 0.15) & (finance_df[\"average_roe\"] < 0.20), \"score_roe\"] = 300\n", + "finance_df.loc[(finance_df[\"average_roe\"] >= 0.10) & (finance_df[\"average_roe\"] < 0.15), \"score_roe\"] = 250\n", + "finance_df[\"score\"] += finance_df[\"score_roe\"]\n", "\n", - "finance_df[finance_df[\"code\"] == '000002.SZ']" + "\n", + "def reset_score_for_average_roe(group):\n", + " group.loc[group['average_roe'].rolling(window=5, min_periods=1).min() < 0, 'score'] = 0\n", + " return group\n", + "\n", + "\n", + "finance_df = finance_df.groupby(\"code\").apply(reset_score_for_average_roe).reset_index(drop=True)" ], "id": "f050d33c4a0cd720", "outputs": [ @@ -242,117 +151,374 @@ "name": "stderr", "output_type": "stream", "text": [ - "/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_54636/2126828454.py:12: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n", - " finance_df[\"score\"] = finance_df.groupby(\"code\").apply(\n" + "C:\\Users\\lanyuanxiaoyao\\AppData\\Local\\Temp\\ipykernel_28824\\1604170078.py:20: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n", + " finance_df = finance_df.groupby(\"code\").apply(reset_score_for_average_roe).reset_index(drop=True)\n" + ] + } + ], + "execution_count": 462 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "总资产报酬率(%) RoA\t总资产报酬率RoA 能真实反映出一家公司的获利能力, 相当于一家公司的 「投资年化率」,当然越高越好。\n", + "RoA均值 >= 15\t100分\n", + "15 > RoA均值 >= 11\t80分\n", + "11 > RoA均值 >= 7\t50分\n", + "7 > RoA均值\t0分" + ], + "id": "6c2e1c602898e342" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-19T16:42:29.363249Z", + "start_time": "2025-01-19T16:42:29.219453Z" + } + }, + "cell_type": "code", + "source": [ + "finance_df[\"prev_total_assets\"] = finance_df.groupby(\"code\")[\"total_assets\"].shift(1)\n", + "finance_df[\"roa\"] = finance_df[\"net_income\"] / ((finance_df[\"prev_total_assets\"] + finance_df[\"total_assets\"]) / 2)\n", + "finance_df[\"average_roa\"] = finance_df.groupby(\"code\")[\"roa\"].rolling(window=5).mean().reset_index(0, drop=True)\n", + "finance_df[\"score_roa\"] = 0\n", + "finance_df.loc[finance_df[\"average_roa\"] >= 0.15, \"score_roa\"] += 100\n", + "finance_df.loc[(finance_df[\"average_roa\"] >= 0.11) & (finance_df[\"average_roa\"] < 0.15), \"score_roa\"] += 80\n", + "finance_df.loc[(finance_df[\"average_roa\"] >= 0.07) & (finance_df[\"average_roa\"] < 0.11), \"score_roa\"] += 50\n", + "finance_df[\"score\"] += finance_df[\"score_roa\"]" + ], + "id": "3b585cf8e2eb5e3", + "outputs": [], + "execution_count": 463 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "税后净利 规模(百万)\t获利规模大,那股价的”长期上涨潜力“也就会越稳健、越确定。选择时,大公司的优先级要高于小公司。\n", + "税后净利均值 >= 10000\t150分\n", + "10000 > 税后净利均值 >= 1000\t100分\n", + "1000 > 税后净利均值\t0分" + ], + "id": "dbcb1d6b23582f3e" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-19T16:42:29.878285Z", + "start_time": "2025-01-19T16:42:29.369862Z" + } + }, + "cell_type": "code", + "source": [ + "finance_df['average_net_income'] = finance_df.groupby('code')['net_income'].transform(lambda x: x.rolling(5).mean())\n", + "finance_df[\"score_net_income\"] = 0\n", + "finance_df.loc[finance_df[\"average_net_income\"] >= 10000 * 10000000, \"score_net_income\"] = 150\n", + "finance_df.loc[(finance_df[\"average_net_income\"] >= 1000 * 10000000) & (\n", + " finance_df[\"average_net_income\"] < 10000 * 10000000), \"score_net_income\"] = 100\n", + "finance_df[\"score\"] += finance_df[\"score_net_income\"]" + ], + "id": "fd5582e080102e20", + "outputs": [], + "execution_count": 464 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "现金状况 分析\t总资产周转率 与 现金与约当现金占总资产的关系,可以看出公司的现金状况是否健康。\n", + "规则①:总资产周转率 > 0.8 且 现金与约当现金占总资产(%) >= 10\t50分\n", + "规则②:总资产周转率 < 0.8 且 现金与约当现金占总资产(%) >= 20\t50分\n", + "不符合 规则① 或 规则②\t0分" + ], + "id": "2c6c934a376eef0d" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-19T16:42:29.905727Z", + "start_time": "2025-01-19T16:42:29.889468Z" + } + }, + "cell_type": "code", + "source": [ + "finance_df[\"prev_total_assets\"] = finance_df.groupby(\"code\")[\"total_assets\"].shift(1)\n", + "finance_df[\"total_assets_turnover_ratio\"] = finance_df[\"total_revenue\"] / (\n", + " (finance_df[\"prev_total_assets\"] + finance_df[\"total_assets\"]) / 2)\n", + "\n", + "finance_df[\"cash_ratio\"] = finance_df[\"cash\"] / finance_df[\"total_assets\"]\n", + "\n", + "finance_df[\"score_assets_turnover_and_cash\"] = 0\n", + "finance_df.loc[(finance_df[\"total_assets_turnover_ratio\"] >= 0.8) & (\n", + " finance_df[\"cash_ratio\"] >= 0.1), \"score_assets_turnover_and_cash\"] = 50\n", + "finance_df.loc[(finance_df[\"total_assets_turnover_ratio\"] < 0.8) & (\n", + " finance_df[\"cash_ratio\"] >= 0.2), \"score_assets_turnover_and_cash\"] = 50\n", + "finance_df[\"score\"] += finance_df[\"score_assets_turnover_and_cash\"]" + ], + "id": "bc92e050c82c3768", + "outputs": [], + "execution_count": 465 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "收现日数(日)\t平均收现日数越短,说明公司的经营能力越强。\n", + "30 >= 平均收现日数\t20分\n", + "平均收现日数 > 30\t0分\n", + "\n", + "销货日数(日)\t平均销货日数越短,说明公司商品越畅销。\n", + "30 >= 平均销货日数\t20分\n", + "平均销货日数 > 30\t0分\n", + "\n", + "收现日数+销货日数(日)\t生意周期 是否足够优秀,越短说明每年能做的生意趟数越多,经营能力就越强。\n", + "40 >= 收现日数+销货日数\t20分\n", + "60 >= 收现日数+销货日数 > 40\t10分\n", + "平均销货日数 > 60\t0分" + ], + "id": "41ac526b0296b44b" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-19T16:42:29.923829Z", + "start_time": "2025-01-19T16:42:29.916781Z" + } + }, + "cell_type": "code", + "source": [ + "# 收现日数\n", + "finance_df[\"collection_cash_period\"] = 360 / (finance_df[\"total_revenue\"] / finance_df[\"accounts_receivable\"])\n", + "# 销货日数\n", + "finance_df[\"sales_period\"] = 360 / (finance_df[\"operating_costs\"] / finance_df[\"accounts_receivable\"])\n", + "\n", + "finance_df[\"score_collection_cash_period\"] = 0\n", + "finance_df.loc[(not finance_df[\"score_collection_cash_period\"].isna) & (\n", + " finance_df[\"collection_cash_period\"] < 30), \"score_collection_cash_period\"] = 20\n", + "finance_df[\"score\"] += finance_df[\"score_collection_cash_period\"]\n", + "\n", + "finance_df[\"score_sales_period\"] = 0\n", + "finance_df.loc[\n", + " (not finance_df[\"score_sales_period\"].isna) & (finance_df[\"score_sales_period\"] < 30), \"score_sales_period\"] = 20\n", + "finance_df[\"score\"] += finance_df[\"score_sales_period\"]\n", + "\n", + "finance_df[\"score_collection_cash_period_and_sales_period\"] = 0\n", + "finance_df.loc[(finance_df[\"collection_cash_period\"] + finance_df[\n", + " \"sales_period\"]) < 40, \"score_collection_cash_period_and_sales_period\"] = 20\n", + "finance_df.loc[(finance_df[\"collection_cash_period\"] + finance_df[\n", + " \"sales_period\"]) < 60, \"score_collection_cash_period_and_sales_period\"] = 10\n", + "finance_df[\"score\"] += finance_df[\"score_collection_cash_period_and_sales_period\"]" + ], + "id": "baeb44a4fb28b60b", + "outputs": [], + "execution_count": 466 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "毛利率(%)\t毛利率 是否保持平稳,不大起大落。\n", + "30% >= 毛利率平均波动幅度\t50分\n", + "毛利率平均波动幅度 > 30%\t0分" + ], + "id": "a53bfdb799df8f48" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-19T16:42:30.005541Z", + "start_time": "2025-01-19T16:42:29.935348Z" + } + }, + "cell_type": "code", + "source": [ + "finance_df[\"gross_profit_ratio\"] = (finance_df[\"total_revenue\"] - finance_df[\"operating_costs\"]) / finance_df[\n", + " \"total_revenue\"]\n", + "finance_df[\"gross_profit_ratio_std\"] = finance_df.groupby(\"code\")[\"gross_profit_ratio\"].rolling(\n", + " window=5).std().reset_index(0, drop=True)\n", + "finance_df[\"score_gross_profit_ratio\"] = 0\n", + "finance_df[(not finance_df[\"gross_profit_ratio_std\"].isna) & (finance_df[\"gross_profit_ratio_std\"] < 30)] = 50\n", + "finance_df[\"score\"] += finance_df[\"score_gross_profit_ratio\"]" + ], + "id": "9d23bdf60a1839c9", + "outputs": [], + "execution_count": 467 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "经营安全边际率(%)\t经营安全边际率越高,说明公司能够很好的控制成本,把大部分利润转化成实际收益, 获利能力很强,有利于抵御经济波动和价格竞争等影响。\n", + "经营安全边际率 >= 70\t50分\n", + "70 > 经营安全边际率 >= 50\t30分\n", + "50 > 经营安全边际率 >= 30\t10分\n", + "30 > 经营安全边际率\t0分" + ], + "id": "6613ab8263d4afef" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-19T16:42:30.022774Z", + "start_time": "2025-01-19T16:42:30.016550Z" + } + }, + "cell_type": "code", + "source": [ + "finance_df[\"operating_profit_ratio\"] = finance_df[\"operating_profit\"] / finance_df[\"total_revenue\"]\n", + "finance_df[\"operating_safety_margin\"] = finance_df[\"operating_profit_ratio\"] / finance_df[\"gross_profit_ratio\"]\n", + "finance_df[\"score_operating_safety_margin\"] = 0\n", + "finance_df.loc[finance_df[\"operating_safety_margin\"] >= 70, \"score_operating_safety_margin\"] = 50\n", + "finance_df.loc[finance_df[\"operating_safety_margin\"] >= 50, \"score_operating_safety_margin\"] = 30\n", + "finance_df.loc[finance_df[\"operating_safety_margin\"] >= 30, \"score_operating_safety_margin\"] = 10\n", + "finance_df[\"score\"] += finance_df[\"score_operating_safety_margin\"]" + ], + "id": "f7d9486af89cb710", + "outputs": [], + "execution_count": 468 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "税后净利\n", + "年份由近(A)~远(E)\t公司赚的钱是否在逐年增长,是股价能长期上涨的基础。\n", + "A年 > B年 (+) / A年 < B年 (-)\t+30分 / -30分\n", + "B年 > C年 (+) / B年 < C年 (-)\t+25分 / -25分\n", + "C年 > D年 (+) / C年 < D年 (-)\t+20分 / -20分\n", + "D年 > E年 (+) / D年 < E年 (-)\t+15分 / -15分" + ], + "id": "2ee3712525455954" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-19T16:42:46.378919Z", + "start_time": "2025-01-19T16:42:30.718209Z" + } + }, + "cell_type": "code", + "source": [ + "def score_by_net_income_ascending(group):\n", + " # 计算 score_net_income_1\n", + " group['net_income_shift_1'] = group['net_income'].shift(1)\n", + " group['score_net_income_1'] = (group['net_income'] > group['net_income_shift_1']).map(\n", + " {True: 30, False: -30})\n", + " group = group.mask(pd.isna(group[\"net_income_shift_1\"]), other=0)\n", + " # 计算 score_net_income_2\n", + " group['net_income_shift_2'] = group['net_income'].shift(2)\n", + " group['score_net_income_2'] = (group['net_income_shift_1'] > group['net_income_shift_2']).map(\n", + " {True: 25, False: -25})\n", + " # 计算 score_net_income_3\n", + " group['net_income_shift_3'] = group['net_income'].shift(3)\n", + " group['score_net_income_3'] = (group['net_income_shift_2'] > group['net_income_shift_3']).map(\n", + " {True: 20, False: -20})\n", + " # 计算 score_net_income_4\n", + " group['net_income_shift_4'] = group['net_income'].shift(4)\n", + " group['score_net_income_4'] = (group['net_income_shift_3'] > group['net_income_shift_4']).map(\n", + " {True: 15, False: -15}).fillna(0)\n", + " return group\n", + "\n", + "\n", + "finance_df = finance_df.groupby(\"code\").apply(score_by_net_income_ascending).reset_index(drop=True)\n", + "finance_df[\"score_net_income_ascending\"] = np.sum(\n", + " [finance_df[\"score_net_income_1\"], finance_df[\"score_net_income_2\"], finance_df[\"score_net_income_3\"],\n", + " finance_df[\"score_net_income_4\"]], axis=0)\n", + "finance_df" + ], + "id": "2d1ca7fc7873ce71", + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\lanyuanxiaoyao\\AppData\\Local\\Temp\\ipykernel_28824\\3206398043.py:22: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n", + " finance_df = finance_df.groupby(\"code\").apply(score_by_net_income_ascending).reset_index(drop=True)\n" ] }, { "data": { "text/plain": [ " code year total_stockholder_interest net_income \\\n", - "1945 000002.SZ 2005 8.581223e+09 1.433426e+09 \n", - "3432 000002.SZ 2006 1.745350e+10 2.422997e+09 \n", - "5449 000002.SZ 2007 3.391952e+10 5.317501e+09 \n", - "7921 000002.SZ 2008 3.881855e+10 4.639869e+09 \n", - "10605 000002.SZ 2009 4.540851e+10 6.430008e+09 \n", - "13934 000002.SZ 2010 5.458620e+10 8.839611e+09 \n", - "17289 000002.SZ 2011 6.783254e+10 1.159961e+10 \n", - "20376 000002.SZ 2012 8.213819e+10 1.566259e+10 \n", - "25215 000002.SZ 2013 1.054394e+11 1.829755e+10 \n", - "29387 000002.SZ 2014 1.158936e+11 1.928752e+10 \n", - "33753 000002.SZ 2015 1.363096e+11 2.594944e+10 \n", - "37463 000002.SZ 2016 1.616766e+11 2.835026e+10 \n", - "42678 000002.SZ 2017 1.866739e+11 3.720839e+10 \n", - "47756 000002.SZ 2018 2.356207e+11 4.927229e+10 \n", - "52944 000002.SZ 2019 2.705791e+11 5.513161e+10 \n", - "57414 000002.SZ 2020 3.498445e+11 5.929812e+10 \n", - "59180 000002.SZ 2021 3.927728e+11 3.806953e+10 \n", - "62929 000002.SZ 2022 4.049915e+11 3.755091e+10 \n", - "68422 000002.SZ 2023 4.029335e+11 2.045556e+10 \n", + "0 0 0 0.000000e+00 0.000000e+00 \n", + "1 000001.SZ 2006 6.474463e+09 1.302907e+09 \n", + "2 000001.SZ 2007 1.300606e+10 2.649903e+09 \n", + "3 000001.SZ 2008 1.640079e+10 6.140350e+08 \n", + "4 000001.SZ 2009 2.046961e+10 5.030729e+09 \n", + "... ... ... ... ... \n", + "70725 871981.BJ 2019 1.484536e+08 1.933833e+07 \n", + "70726 871981.BJ 2020 1.963500e+08 3.113004e+07 \n", + "70727 871981.BJ 2021 4.901179e+08 6.549797e+07 \n", + "70728 871981.BJ 2022 5.238630e+08 4.359533e+07 \n", + "70729 871981.BJ 2023 5.044336e+08 -5.665176e+06 \n", "\n", " total_assets total_revenue inventories accounts_receivable \\\n", - "1945 2.199239e+10 1.055885e+10 1.484948e+10 3.773077e+08 \n", - "3432 4.991984e+10 1.791833e+10 3.416711e+10 3.646097e+08 \n", - "5449 1.000945e+11 3.552661e+10 6.647288e+10 8.648830e+08 \n", - "7921 1.192366e+11 4.099178e+10 8.589870e+10 9.227748e+08 \n", - "10605 1.376086e+11 4.888101e+10 9.008529e+10 7.131919e+08 \n", - "13934 2.156376e+11 5.071385e+10 1.333335e+11 1.594025e+09 \n", - "17289 2.962084e+11 7.178275e+10 2.083355e+11 1.514814e+09 \n", - "20376 3.788016e+11 1.031162e+11 2.551641e+11 1.886549e+09 \n", - "25215 4.792053e+11 1.354188e+11 3.311332e+11 3.078970e+09 \n", - "29387 5.084088e+11 1.463880e+11 3.177264e+11 1.894072e+09 \n", - "33753 6.112956e+11 1.955491e+11 3.681219e+11 2.510653e+09 \n", - "37463 8.306742e+11 2.404772e+11 4.673613e+11 2.075257e+09 \n", - "42678 1.165347e+12 2.428971e+11 5.980877e+11 1.432734e+09 \n", - "47756 1.528579e+12 2.976793e+11 7.503026e+11 1.586181e+09 \n", - "52944 1.729929e+12 3.678939e+11 8.970190e+11 1.988076e+09 \n", - "57414 1.869177e+12 4.191117e+11 1.002063e+12 2.992423e+09 \n", - "59180 1.938638e+12 4.527978e+11 1.075617e+12 4.743597e+09 \n", - "62929 1.757124e+12 5.038384e+11 9.070569e+11 7.504692e+09 \n", - "68422 1.504850e+12 4.657391e+11 7.016958e+11 7.293628e+09 \n", + "0 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 \n", + "1 2.605763e+11 7.135218e+09 NaN NaN \n", + "2 3.525394e+11 1.080750e+10 NaN NaN \n", + "3 4.744402e+11 1.451312e+10 NaN NaN \n", + "4 5.878110e+11 1.511444e+10 NaN NaN \n", + "... ... ... ... ... \n", + "70725 3.438787e+08 2.288707e+08 6.439933e+07 9.145441e+07 \n", + "70726 4.407381e+08 3.221584e+08 7.076865e+07 1.028702e+08 \n", + "70727 7.806398e+08 4.748939e+08 1.102946e+08 1.094223e+08 \n", + "70728 8.141886e+08 3.872667e+08 1.034502e+08 7.252802e+07 \n", + "70729 7.671820e+08 3.613133e+08 1.070212e+08 7.962033e+07 \n", "\n", - " operating_costs operating_profit cash \\\n", - "1945 6.884921e+09 1.958371e+09 3.249035e+09 \n", - "3432 1.144126e+10 3.426907e+09 1.074370e+10 \n", - "5449 2.060734e+10 7.652897e+09 1.704650e+10 \n", - "7921 2.500527e+10 6.364790e+09 1.997829e+10 \n", - "10605 3.451472e+10 8.685083e+09 2.300192e+10 \n", - "13934 3.007350e+10 1.189489e+10 3.781693e+10 \n", - "17289 4.322816e+10 1.576322e+10 3.423951e+10 \n", - "20376 6.542161e+10 2.101304e+10 5.229154e+10 \n", - "25215 9.279765e+10 2.426134e+10 4.436541e+10 \n", - "29387 1.025571e+11 2.497936e+10 6.271525e+10 \n", - "33753 1.381506e+11 3.312278e+10 5.318038e+10 \n", - "37463 1.697424e+11 3.902378e+10 8.703212e+10 \n", - "42678 1.600799e+11 5.081292e+10 1.741210e+11 \n", - "47756 1.861042e+11 6.749861e+10 1.884174e+11 \n", - "52944 2.345503e+11 7.661314e+10 1.661946e+11 \n", - "57414 2.965407e+11 7.995864e+10 1.952307e+11 \n", - "59180 3.539771e+11 5.253100e+10 1.493524e+11 \n", - "62929 4.053193e+11 5.200694e+10 1.372076e+11 \n", - "68422 3.947839e+11 2.925170e+10 9.981376e+10 \n", + " operating_costs operating_profit ... score_operating_safety_margin \\\n", + "0 0.000000e+00 0.000000e+00 ... 0 \n", + "1 NaN 1.905169e+09 ... 0 \n", + "2 NaN 3.721942e+09 ... 0 \n", + "3 NaN 8.034260e+08 ... 0 \n", + "4 NaN 6.159127e+09 ... 0 \n", + "... ... ... ... ... \n", + "70725 1.759984e+08 1.982603e+07 ... 0 \n", + "70726 2.444144e+08 3.466142e+07 ... 0 \n", + "70727 3.501988e+08 7.194507e+07 ... 0 \n", + "70728 3.141146e+08 2.827675e+07 ... 0 \n", + "70729 3.220560e+08 -1.192680e+07 ... 0 \n", "\n", - " operating_net_cash_flow score prev_total_stockholder_interest \\\n", - "1945 8.434391e+08 0.0 NaN \n", - "3432 -3.024121e+09 0.0 8.581223e+09 \n", - "5449 -1.043772e+10 0.0 1.745350e+10 \n", - "7921 -3.415183e+07 0.0 3.391952e+10 \n", - "10605 9.253351e+09 0.0 3.881855e+10 \n", - "13934 2.237255e+09 250.0 4.540851e+10 \n", - "17289 3.389425e+09 0.0 5.458620e+10 \n", - "20376 3.725958e+09 0.0 6.783254e+10 \n", - "25215 1.923869e+09 300.0 8.213819e+10 \n", - "29387 4.172482e+10 0.0 1.054394e+11 \n", - "33753 1.604602e+10 0.0 1.158936e+11 \n", - "37463 3.956613e+10 400.0 1.363096e+11 \n", - "42678 8.232283e+10 250.0 1.616766e+11 \n", - "47756 3.361818e+10 0.0 1.866739e+11 \n", - "52944 4.568681e+10 400.0 2.356207e+11 \n", - "57414 5.318802e+10 0.0 2.705791e+11 \n", - "59180 4.113161e+09 250.0 3.498445e+11 \n", - "62929 2.750449e+09 0.0 3.927728e+11 \n", - "68422 3.912324e+09 300.0 4.049915e+11 \n", + " net_income_shift_1 score_net_income_1 net_income_shift_2 \\\n", + "0 0.000000e+00 0 NaN \n", + "1 3.110076e+08 30 NaN \n", + "2 1.302907e+09 30 0.000000e+00 \n", + "3 2.649903e+09 -30 1.302907e+09 \n", + "4 6.140350e+08 30 2.649903e+09 \n", + "... ... ... ... \n", + "70725 1.875294e+07 30 9.625220e+06 \n", + "70726 1.933833e+07 30 1.875294e+07 \n", + "70727 3.113004e+07 30 1.933833e+07 \n", + "70728 6.549797e+07 -30 3.113004e+07 \n", + "70729 4.359533e+07 -30 6.549797e+07 \n", "\n", - " roe average_roe \n", - "1945 NaN NaN \n", - "3432 0.186136 NaN \n", - "5449 0.207015 NaN \n", - "7921 0.127577 NaN \n", - "10605 0.152683 NaN \n", - "13934 0.176802 0.170043 \n", - "17289 0.189507 0.170717 \n", - "20376 0.208875 0.171089 \n", - "25215 0.195093 0.184592 \n", - "29387 0.174285 0.188912 \n", - "33753 0.205782 0.194708 \n", - "37463 0.190279 0.194863 \n", - "42678 0.213626 0.195813 \n", - "47756 0.233355 0.203465 \n", - "52944 0.217825 0.212174 \n", - "57414 0.191154 0.209248 \n", - "59180 0.102528 0.191698 \n", - "62929 0.094140 0.167801 \n", - "68422 0.050637 0.131257 " + " score_net_income_2 net_income_shift_3 score_net_income_3 \\\n", + "0 -25 NaN -20 \n", + "1 -25 NaN -20 \n", + "2 25 NaN -20 \n", + "3 25 0.000000e+00 20 \n", + "4 -25 1.302907e+09 20 \n", + "... ... ... ... \n", + "70725 25 0.000000e+00 20 \n", + "70726 25 9.625220e+06 20 \n", + "70727 25 1.875294e+07 20 \n", + "70728 25 1.933833e+07 20 \n", + "70729 -25 3.113004e+07 20 \n", + "\n", + " net_income_shift_4 score_net_income_4 score_net_income_ascending \n", + "0 NaN -15 -60 \n", + "1 NaN -15 -30 \n", + "2 NaN -15 20 \n", + "3 NaN -15 0 \n", + "4 0.00 15 40 \n", + "... ... ... ... \n", + "70725 NaN -15 60 \n", + "70726 0.00 15 90 \n", + "70727 9625220.11 15 90 \n", + "70728 18752944.38 15 30 \n", + "70729 19338331.78 15 -20 \n", + "\n", + "[70730 rows x 46 columns]" ], "text/html": [ "
\n", @@ -383,801 +549,299 @@ " accounts_receivable\n", " operating_costs\n", " operating_profit\n", - " cash\n", - " operating_net_cash_flow\n", - " score\n", - " prev_total_stockholder_interest\n", - " roe\n", - " average_roe\n", - " \n", - " \n", - " \n", - " \n", - " 1945\n", - " 000002.SZ\n", - " 2005\n", - " 8.581223e+09\n", - " 1.433426e+09\n", - " 2.199239e+10\n", - " 1.055885e+10\n", - " 1.484948e+10\n", - " 3.773077e+08\n", - " 6.884921e+09\n", - " 1.958371e+09\n", - " 3.249035e+09\n", - " 8.434391e+08\n", - " 0.0\n", - " NaN\n", - " NaN\n", - " NaN\n", - " \n", - " \n", - " 3432\n", - " 000002.SZ\n", - " 2006\n", - " 1.745350e+10\n", - " 2.422997e+09\n", - " 4.991984e+10\n", - " 1.791833e+10\n", - " 3.416711e+10\n", - " 3.646097e+08\n", - " 1.144126e+10\n", - " 3.426907e+09\n", - " 1.074370e+10\n", - " -3.024121e+09\n", - " 0.0\n", - " 8.581223e+09\n", - " 0.186136\n", - " NaN\n", - " \n", - " \n", - " 5449\n", - " 000002.SZ\n", - " 2007\n", - " 3.391952e+10\n", - " 5.317501e+09\n", - " 1.000945e+11\n", - " 3.552661e+10\n", - " 6.647288e+10\n", - " 8.648830e+08\n", - " 2.060734e+10\n", - " 7.652897e+09\n", - " 1.704650e+10\n", - " -1.043772e+10\n", - " 0.0\n", - " 1.745350e+10\n", - " 0.207015\n", - " NaN\n", - " \n", - " \n", - " 7921\n", - " 000002.SZ\n", - " 2008\n", - " 3.881855e+10\n", - " 4.639869e+09\n", - " 1.192366e+11\n", - " 4.099178e+10\n", - " 8.589870e+10\n", - " 9.227748e+08\n", - " 2.500527e+10\n", - " 6.364790e+09\n", - " 1.997829e+10\n", - " -3.415183e+07\n", - " 0.0\n", - " 3.391952e+10\n", - " 0.127577\n", - " NaN\n", - " \n", - " \n", - " 10605\n", - " 000002.SZ\n", - " 2009\n", - " 4.540851e+10\n", - " 6.430008e+09\n", - " 1.376086e+11\n", - " 4.888101e+10\n", - " 9.008529e+10\n", - " 7.131919e+08\n", - " 3.451472e+10\n", - " 8.685083e+09\n", - " 2.300192e+10\n", - " 9.253351e+09\n", - " 0.0\n", - " 3.881855e+10\n", - " 0.152683\n", - " NaN\n", - " \n", - " \n", - " 13934\n", - " 000002.SZ\n", - " 2010\n", - " 5.458620e+10\n", - " 8.839611e+09\n", - " 2.156376e+11\n", - " 5.071385e+10\n", - " 1.333335e+11\n", - " 1.594025e+09\n", - " 3.007350e+10\n", - " 1.189489e+10\n", - " 3.781693e+10\n", - " 2.237255e+09\n", - " 250.0\n", - " 4.540851e+10\n", - " 0.176802\n", - " 0.170043\n", - " \n", - " \n", - " 17289\n", - " 000002.SZ\n", - " 2011\n", - " 6.783254e+10\n", - " 1.159961e+10\n", - " 2.962084e+11\n", - " 7.178275e+10\n", - " 2.083355e+11\n", - " 1.514814e+09\n", - " 4.322816e+10\n", - " 1.576322e+10\n", - " 3.423951e+10\n", - " 3.389425e+09\n", - " 0.0\n", - " 5.458620e+10\n", - " 0.189507\n", - " 0.170717\n", - " \n", - " \n", - " 20376\n", - " 000002.SZ\n", - " 2012\n", - " 8.213819e+10\n", - " 1.566259e+10\n", - " 3.788016e+11\n", - " 1.031162e+11\n", - " 2.551641e+11\n", - " 1.886549e+09\n", - " 6.542161e+10\n", - " 2.101304e+10\n", - " 5.229154e+10\n", - " 3.725958e+09\n", - " 0.0\n", - " 6.783254e+10\n", - " 0.208875\n", - " 0.171089\n", - " \n", - " \n", - " 25215\n", - " 000002.SZ\n", - " 2013\n", - " 1.054394e+11\n", - " 1.829755e+10\n", - " 4.792053e+11\n", - " 1.354188e+11\n", - " 3.311332e+11\n", - " 3.078970e+09\n", - " 9.279765e+10\n", - " 2.426134e+10\n", - " 4.436541e+10\n", - " 1.923869e+09\n", - " 300.0\n", - " 8.213819e+10\n", - " 0.195093\n", - " 0.184592\n", - " \n", - " \n", - " 29387\n", - " 000002.SZ\n", - " 2014\n", - " 1.158936e+11\n", - " 1.928752e+10\n", - " 5.084088e+11\n", - " 1.463880e+11\n", - " 3.177264e+11\n", - " 1.894072e+09\n", - " 1.025571e+11\n", - " 2.497936e+10\n", - " 6.271525e+10\n", - " 4.172482e+10\n", - " 0.0\n", - " 1.054394e+11\n", - " 0.174285\n", - " 0.188912\n", - " \n", - " \n", - " 33753\n", - " 000002.SZ\n", - " 2015\n", - " 1.363096e+11\n", - " 2.594944e+10\n", - " 6.112956e+11\n", - " 1.955491e+11\n", - " 3.681219e+11\n", - " 2.510653e+09\n", - " 1.381506e+11\n", - " 3.312278e+10\n", - " 5.318038e+10\n", - " 1.604602e+10\n", - " 0.0\n", - " 1.158936e+11\n", - " 0.205782\n", - " 0.194708\n", - " \n", - " \n", - " 37463\n", - " 000002.SZ\n", - " 2016\n", - " 1.616766e+11\n", - " 2.835026e+10\n", - " 8.306742e+11\n", - " 2.404772e+11\n", - " 4.673613e+11\n", - " 2.075257e+09\n", - " 1.697424e+11\n", - " 3.902378e+10\n", - " 8.703212e+10\n", - " 3.956613e+10\n", - " 400.0\n", - " 1.363096e+11\n", - " 0.190279\n", - " 0.194863\n", - " \n", - " \n", - " 42678\n", - " 000002.SZ\n", - " 2017\n", - " 1.866739e+11\n", - " 3.720839e+10\n", - " 1.165347e+12\n", - " 2.428971e+11\n", - " 5.980877e+11\n", - " 1.432734e+09\n", - " 1.600799e+11\n", - " 5.081292e+10\n", - " 1.741210e+11\n", - " 8.232283e+10\n", - " 250.0\n", - " 1.616766e+11\n", - " 0.213626\n", - " 0.195813\n", - " \n", - " \n", - " 47756\n", - " 000002.SZ\n", - " 2018\n", - " 2.356207e+11\n", - " 4.927229e+10\n", - " 1.528579e+12\n", - " 2.976793e+11\n", - " 7.503026e+11\n", - " 1.586181e+09\n", - " 1.861042e+11\n", - " 6.749861e+10\n", - " 1.884174e+11\n", - " 3.361818e+10\n", - " 0.0\n", - " 1.866739e+11\n", - " 0.233355\n", - " 0.203465\n", - " \n", - " \n", - " 52944\n", - " 000002.SZ\n", - " 2019\n", - " 2.705791e+11\n", - " 5.513161e+10\n", - " 1.729929e+12\n", - " 3.678939e+11\n", - " 8.970190e+11\n", - " 1.988076e+09\n", - " 2.345503e+11\n", - " 7.661314e+10\n", - " 1.661946e+11\n", - " 4.568681e+10\n", - " 400.0\n", - " 2.356207e+11\n", - " 0.217825\n", - " 0.212174\n", - " \n", - " \n", - " 57414\n", - " 000002.SZ\n", - " 2020\n", - " 3.498445e+11\n", - " 5.929812e+10\n", - " 1.869177e+12\n", - " 4.191117e+11\n", - " 1.002063e+12\n", - " 2.992423e+09\n", - " 2.965407e+11\n", - " 7.995864e+10\n", - " 1.952307e+11\n", - " 5.318802e+10\n", - " 0.0\n", - " 2.705791e+11\n", - " 0.191154\n", - " 0.209248\n", - " \n", - " \n", - " 59180\n", - " 000002.SZ\n", - " 2021\n", - " 3.927728e+11\n", - " 3.806953e+10\n", - " 1.938638e+12\n", - " 4.527978e+11\n", - " 1.075617e+12\n", - " 4.743597e+09\n", - " 3.539771e+11\n", - " 5.253100e+10\n", - " 1.493524e+11\n", - " 4.113161e+09\n", - " 250.0\n", - " 3.498445e+11\n", - " 0.102528\n", - " 0.191698\n", - " \n", - " \n", - " 62929\n", - " 000002.SZ\n", - " 2022\n", - " 4.049915e+11\n", - " 3.755091e+10\n", - " 1.757124e+12\n", - " 5.038384e+11\n", - " 9.070569e+11\n", - " 7.504692e+09\n", - " 4.053193e+11\n", - " 5.200694e+10\n", - " 1.372076e+11\n", - " 2.750449e+09\n", - " 0.0\n", - " 3.927728e+11\n", - " 0.094140\n", - " 0.167801\n", - " \n", - " \n", - " 68422\n", - " 000002.SZ\n", - " 2023\n", - " 4.029335e+11\n", - " 2.045556e+10\n", - " 1.504850e+12\n", - " 4.657391e+11\n", - " 7.016958e+11\n", - " 7.293628e+09\n", - " 3.947839e+11\n", - " 2.925170e+10\n", - " 9.981376e+10\n", - " 3.912324e+09\n", - " 300.0\n", - " 4.049915e+11\n", - " 0.050637\n", - " 0.131257\n", - " \n", - " \n", - "\n", - "
" - ] - }, - "execution_count": 150, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 150 - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-17T10:19:25.031141Z", - "start_time": "2025-01-17T10:19:25.020325Z" - } - }, - "cell_type": "code", - "source": [ - "df = pd.DataFrame([[1, 2, 0], [1, 3, 0], [1, -4, 0]], columns=[\"code\", \"average\", \"score\"])\n", - "df[\"condition\"] = df.groupby(\"code\")[\"average\"].transform(\n", - " lambda x: x.rolling(window=2).apply(lambda y: (y < 0).any(), raw=False)\n", - ") > 0\n", - "df[\"score\"].mask(\n", - " df.groupby(\"code\")[\"average\"].transform(\n", - " lambda x: x.rolling(window=2).apply(lambda y: (y < 0).any(), raw=False)\n", - " ) > 0,\n", - " 0\n", - ")\n", - "df" - ], - "id": "1a6a739df5b6f3a9", - "outputs": [ - { - "data": { - "text/plain": [ - " code average score condition\n", - "0 1 2 0 False\n", - "1 1 3 0 False\n", - "2 1 -4 0 True" - ], - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", "
codeaveragescorecondition...score_operating_safety_marginnet_income_shift_1score_net_income_1net_income_shift_2score_net_income_2net_income_shift_3score_net_income_3net_income_shift_4score_net_income_4score_net_income_ascending
0120False00.000000e+000.000000e+000.000000e+000.000000e+000.000000e+000.000000e+000.000000e+000.000000e+00...00.000000e+000NaN-25NaN-20NaN-15-60
113000001.SZ20066.474463e+091.302907e+092.605763e+117.135218e+09NaNNaNNaN1.905169e+09...0False3.110076e+0830NaN-25NaN-20NaN-15-30
21-4000001.SZ20071.300606e+102.649903e+093.525394e+111.080750e+10NaNNaNNaN3.721942e+09...0True1.302907e+09300.000000e+0025NaN-20NaN-1520
3000001.SZ20081.640079e+106.140350e+084.744402e+111.451312e+10NaNNaNNaN8.034260e+08...02.649903e+09-301.302907e+09250.000000e+0020NaN-150
4000001.SZ20092.046961e+105.030729e+095.878110e+111.511444e+10NaNNaNNaN6.159127e+09...06.140350e+08302.649903e+09-251.302907e+09200.001540
..................................................................
70725871981.BJ20191.484536e+081.933833e+073.438787e+082.288707e+086.439933e+079.145441e+071.759984e+081.982603e+07...01.875294e+07309.625220e+06250.000000e+0020NaN-1560
70726871981.BJ20201.963500e+083.113004e+074.407381e+083.221584e+087.076865e+071.028702e+082.444144e+083.466142e+07...01.933833e+07301.875294e+07259.625220e+06200.001590
70727871981.BJ20214.901179e+086.549797e+077.806398e+084.748939e+081.102946e+081.094223e+083.501988e+087.194507e+07...03.113004e+07301.933833e+07251.875294e+07209625220.111590
70728871981.BJ20225.238630e+084.359533e+078.141886e+083.872667e+081.034502e+087.252802e+073.141146e+082.827675e+07...06.549797e+07-303.113004e+07251.933833e+072018752944.381530
70729871981.BJ20235.044336e+08-5.665176e+067.671820e+083.613133e+081.070212e+087.962033e+073.220560e+08-1.192680e+07...04.359533e+07-306.549797e+07-253.113004e+072019338331.7815-20
\n", + "

70730 rows × 46 columns

\n", "
" ] }, - "execution_count": 165, + "execution_count": 469, "metadata": {}, "output_type": "execute_result" } ], - "execution_count": 165 + "execution_count": 469 }, { "metadata": {}, - "cell_type": "markdown", - "source": [ - "总资产报酬率(%) RoA\t总资产报酬率RoA 能真实反映出一家公司的获利能力, 相当于一家公司的 「投资年化率」,当然越高越好。\n", - "RoA均值 >= 15\t100分\n", - "15 > RoA均值 >= 11\t80分\n", - "11 > RoA均值 >= 7\t50分\n", - "7 > RoA均值\t0分" - ], - "id": "6c2e1c602898e342" - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:23:20.494927Z", - "start_time": "2025-01-14T14:23:12.064079Z" - } - }, - "cell_type": "code", - "source": [ - "def cal_roa(df):\n", - " df[\"prev_total_assets\"] = df[\"total_assets\"].shift(1)\n", - " df[\"roa\"] = df[\"net_income\"] / ((df[\"prev_total_assets\"] + df[\"total_assets\"]) / 2)\n", - " df.drop(columns=[\"prev_total_assets\"], inplace=True)\n", - "\n", - "\n", - "def score_by_roa(code):\n", - " temp_df = finance_df[finance_df[\"code\"] == code].copy()\n", - " cal_roa(temp_df)\n", - "\n", - " average_roa = temp_df.nlargest(5, \"year\")[\"roa\"].mean() * 100\n", - "\n", - " if average_roa >= 15:\n", - " return 100\n", - " elif average_roa >= 11:\n", - " return 80\n", - " elif average_roa >= 7:\n", - " return 50\n", - " else:\n", - " return 0\n", - "\n", - "\n", - "codes = list(map(lambda x: add_score(x, score_by_roa(x[0])), codes))" - ], - "id": "25d1d5c0f7de460c", - "outputs": [], - "execution_count": 8 - }, - { - "metadata": {}, - "cell_type": "markdown", - "source": [ - "税后净利 规模(百万)\t获利规模大,那股价的”长期上涨潜力“也就会越稳健、越确定。选择时,大公司的优先级要高于小公司。\n", - "税后净利均值 >= 10000\t150分\n", - "10000 > 税后净利均值 >= 1000\t100分\n", - "1000 > 税后净利均值\t0分" - ], - "id": "dbcb1d6b23582f3e" - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:23:29.214393Z", - "start_time": "2025-01-14T14:23:22.256675Z" - } - }, - "cell_type": "code", - "source": [ - "def score_by_net_income(code):\n", - " temp_df = finance_df[finance_df[\"code\"] == code].copy()\n", - " average_net_income = temp_df.nlargest(5, \"year\")[\"net_income\"].mean()\n", - "\n", - " if average_net_income >= 10000 * 10000000:\n", - " return 150\n", - " elif average_net_income >= 1000 * 10000000:\n", - " return 100\n", - " else:\n", - " return 0\n", - "\n", - "\n", - "codes = list(map(lambda x: add_score(x, score_by_net_income(x[0])), codes))" - ], - "id": "2f19c7fbb0afaa49", - "outputs": [], - "execution_count": 9 - }, - { - "metadata": {}, - "cell_type": "markdown", - "source": [ - "现金状况 分析\t总资产周转率 与 现金与约当现金占总资产的关系,可以看出公司的现金状况是否健康。\n", - "规则①:总资产周转率 > 0.8 且 现金与约当现金占总资产(%) >= 10\t50分\n", - "规则②:总资产周转率 < 0.8 且 现金与约当现金占总资产(%) >= 20\t50分\n", - "不符合 规则① 或 规则②\t0分" - ], - "id": "2c6c934a376eef0d" - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:23:39.246944Z", - "start_time": "2025-01-14T14:23:30.739476Z" - } - }, - "cell_type": "code", - "source": [ - "def cal_total_assets_turnover_ratio(df):\n", - " df[\"prev_total_assets\"] = df[\"total_assets\"].shift(1)\n", - " df[\"total_assets_turnover_ratio\"] = df[\"total_revenue\"] / ((df[\"prev_total_assets\"] + df[\"total_assets\"]) / 2)\n", - " df.drop(columns=[\"prev_total_assets\"], inplace=True)\n", - "\n", - "\n", - "def cal_cash_ratio(df):\n", - " df[\"cash_ratio\"] = df[\"cash\"] / df[\"total_assets\"]\n", - "\n", - "\n", - "def score_by_assets_turnover_and_cash(code):\n", - " temp_df = finance_df[finance_df[\"code\"] == code].copy()\n", - "\n", - " # 总资产周转率\n", - " cal_total_assets_turnover_ratio(temp_df)\n", - " total_assets_turnover_ratio = \\\n", - " temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"total_assets_turnover_ratio\"].values[0] * 100\n", - "\n", - " # 现金比率\n", - " cal_cash_ratio(temp_df)\n", - " cash_ratio = temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"cash_ratio\"].values[0] * 100\n", - "\n", - " if total_assets_turnover_ratio > 80 and cash_ratio >= 10:\n", - " return 50\n", - " elif total_assets_turnover_ratio < 80 and cash_ratio >= 20:\n", - " return 50\n", - " else:\n", - " return 0\n", - "\n", - "\n", - "codes = list(map(lambda x: add_score(x, score_by_assets_turnover_and_cash(x[0])), codes))" - ], - "id": "31be2cb671b7adde", - "outputs": [], - "execution_count": 10 - }, - { - "metadata": {}, - "cell_type": "markdown", - "source": [ - "收现日数(日)\t平均收现日数越短,说明公司的经营能力越强。\n", - "30 >= 平均收现日数\t20分\n", - "平均收现日数 > 30\t0分\n", - "\n", - "销货日数(日)\t平均销货日数越短,说明公司商品越畅销。\n", - "30 >= 平均销货日数\t20分\n", - "平均销货日数 > 30\t0分\n", - "\n", - "收现日数+销货日数(日)\t生意周期 是否足够优秀,越短说明每年能做的生意趟数越多,经营能力就越强。\n", - "40 >= 收现日数+销货日数\t20分\n", - "60 >= 收现日数+销货日数 > 40\t10分\n", - "平均销货日数 > 60\t0分" - ], - "id": "41ac526b0296b44b" - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:23:47.733800Z", - "start_time": "2025-01-14T14:23:40.102117Z" - } - }, - "cell_type": "code", - "source": [ - "# 收现日数\n", - "def cal_collection_cash_period(df):\n", - " df[\"collection_cash_period\"] = 360 / (df[\"total_revenue\"] / df[\"accounts_receivable\"])\n", - "\n", - "\n", - "# 销货日数\n", - "def cal_sales_period(df):\n", - " df[\"sales_period\"] = 360 / (df[\"operating_costs\"] / df[\"inventories\"])\n", - "\n", - "\n", - "def score_by_collection_cash_period_and_sales_period(code):\n", - " temp_df = finance_df[finance_df[\"code\"] == code].copy()\n", - "\n", - " cal_collection_cash_period(temp_df)\n", - " collection_cash_period = temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"collection_cash_period\"].values[0]\n", - "\n", - " cal_sales_period(temp_df)\n", - " sales_period = temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"sales_period\"].values[0]\n", - "\n", - " score = 0\n", - " if collection_cash_period < 30:\n", - " score += 20\n", - "\n", - " if sales_period < 30:\n", - " score += 20\n", - "\n", - " if (collection_cash_period + sales_period) < 40:\n", - " score += 20\n", - " elif (collection_cash_period + sales_period) < 60:\n", - " score += 10\n", - "\n", - " return score\n", - "\n", - "\n", - "codes = list(map(lambda x: add_score(x, score_by_collection_cash_period_and_sales_period(x[0])), codes))" - ], - "id": "ab6ff79c2650db7c", - "outputs": [], - "execution_count": 11 - }, - { - "metadata": {}, - "cell_type": "markdown", - "source": [ - "毛利率(%)\t毛利率 是否保持平稳,不大起大落。\n", - "30% >= 毛利率平均波动幅度\t50分\n", - "毛利率平均波动幅度 > 30%\t0分" - ], - "id": "a53bfdb799df8f48" - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:23:57.280972Z", - "start_time": "2025-01-14T14:23:49.457909Z" - } - }, - "cell_type": "code", - "source": [ - "# 毛利率\n", - "def cal_gross_profit_ratio(df):\n", - " df[\"gross_profit_ratio\"] = (df[\"total_revenue\"] - df[\"operating_costs\"]) / df[\"total_revenue\"]\n", - "\n", - "\n", - "def score_by_gross_profit_ratio_volatility(code):\n", - " temp_df = finance_df[finance_df[\"code\"] == code].copy()\n", - " cal_gross_profit_ratio(temp_df)\n", - " gross_profit_ratio_std = temp_df.nlargest(5, \"year\")[\"gross_profit_ratio\"].std() * 100\n", - "\n", - " if gross_profit_ratio_std < 30:\n", - " return 50\n", - " else:\n", - " return 0\n", - "\n", - "\n", - "codes = list(map(lambda x: add_score(x, score_by_gross_profit_ratio_volatility(x[0])), codes))" - ], - "id": "8e58e0114851ebcb", - "outputs": [], - "execution_count": 12 - }, - { - "metadata": {}, - "cell_type": "markdown", - "source": [ - "经营安全边际率(%)\t经营安全边际率越高,说明公司能够很好的控制成本,把大部分利润转化成实际收益, 获利能力很强,有利于抵御经济波动和价格竞争等影响。\n", - "经营安全边际率 >= 70\t50分\n", - "70 > 经营安全边际率 >= 50\t30分\n", - "50 > 经营安全边际率 >= 30\t10分\n", - "30 > 经营安全边际率\t0分" - ], - "id": "6613ab8263d4afef" - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:24:05.675449Z", - "start_time": "2025-01-14T14:23:58.156821Z" - } - }, - "cell_type": "code", - "source": [ - "# 经营安全边际\n", - "def cal_operating_safety_margin(df):\n", - " # 经营利润率\n", - " df[\"operating_profit_ratio\"] = df[\"operating_profit\"] / df[\"total_revenue\"]\n", - " df[\"operating_safety_margin\"] = df[\"operating_profit_ratio\"] / df[\"gross_profit_ratio\"]\n", - "\n", - "\n", - "def score_by_operating_safety_margin(code):\n", - " temp_df = finance_df[finance_df[\"code\"] == code].copy()\n", - " cal_gross_profit_ratio(temp_df)\n", - " cal_operating_safety_margin(temp_df)\n", - "\n", - " operating_safety_margin = temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"operating_safety_margin\"].values[0]\n", - "\n", - " if operating_safety_margin >= 70:\n", - " return 50\n", - " elif operating_safety_margin >= 50:\n", - " return 30\n", - " elif operating_safety_margin >= 30:\n", - " return 10\n", - " else:\n", - " return 0\n", - "\n", - "\n", - "codes = list(map(lambda x: add_score(x, score_by_operating_safety_margin(x[0])), codes))" - ], - "id": "d07048f574e163ab", - "outputs": [], - "execution_count": 13 - }, - { - "metadata": {}, - "cell_type": "markdown", - "source": [ - "税后净利\n", - "年份由近(A)~远(E)\t公司赚的钱是否在逐年增长,是股价能长期上涨的基础。\n", - "A年 > B年 (+) / A年 < B年 (-)\t+30分 / -30分\n", - "B年 > C年 (+) / B年 < C年 (-)\t+25分 / -25分\n", - "C年 > D年 (+) / C年 < D年 (-)\t+20分 / -20分\n", - "D年 > E年 (+) / D年 < E年 (-)\t+15分 / -15分" - ], - "id": "2ee3712525455954" - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:24:13.783225Z", - "start_time": "2025-01-14T14:24:06.605156Z" - } - }, "cell_type": "code", "source": [ "def score_by_net_income_ascending(code):\n", @@ -1213,15 +877,10 @@ ], "id": "4ab6a7b485dc9349", "outputs": [], - "execution_count": 14 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:24:21.962980Z", - "start_time": "2025-01-14T14:24:14.785970Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "def score_by_operating_net_cash_flow_ascending(code):\n", @@ -1257,340 +916,36 @@ ], "id": "d6644089e803a79d", "outputs": [], - "execution_count": 15 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:24:24.969522Z", - "start_time": "2025-01-14T14:24:24.957769Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "df = pd.DataFrame(\n", " codes,\n", " columns=[\"code\", \"name\", \"score\", \"roe_score\", \"roa_score\", \"net_income\", \"assets_turnover_and_cash\",\n", - " \"collection_cash_period_and_sales_period\", \"gross_profit_ratio_volatility\",\n", - " \"operating_safety_margin\", \"net_income_ascending\",\n", - " \"operating_net_cash_flow_ascending\"]\n", + " \"collection_cash_period_and_sales_period\", \"gross_profit_ratio_volatility\",\n", + " \"operating_safety_margin\", \"net_income_ascending\",\n", + " \"operating_net_cash_flow_ascending\"]\n", ")\n", "df.sort_values(by=\"score\", ascending=False, inplace=True)\n", "df" ], "id": "ef9e6259efc1c1d0", - "outputs": [ - { - "data": { - "text/plain": [ - " code name score roe_score roa_score net_income \\\n", - "2393 600519.SH 贵州茅台 950 500 100 100 \n", - "323 000858.SZ 五粮液 910 450 100 100 \n", - "3238 603688.SH 石英股份 850 500 100 0 \n", - "144 000568.SZ 泸州老窖 850 450 100 0 \n", - "2336 600438.SH 通威股份 840 450 80 100 \n", - "... ... ... ... ... ... ... \n", - "1703 300436.SZ 广生堂 -100 0 0 0 \n", - "2441 600579.SH 克劳斯 -100 0 0 0 \n", - "1054 002672.SZ 东江环保 -130 0 0 0 \n", - "1488 300204.SZ 舒泰神 -130 0 0 0 \n", - "1619 300345.SZ 华民股份 -130 0 0 0 \n", - "\n", - " assets_turnover_and_cash collection_cash_period_and_sales_period \\\n", - "2393 50 20 \n", - "323 50 20 \n", - "3238 50 0 \n", - "144 50 20 \n", - "2336 50 50 \n", - "... ... ... \n", - "1703 0 0 \n", - "2441 0 0 \n", - "1054 0 0 \n", - "1488 0 0 \n", - "1619 0 0 \n", - "\n", - " gross_profit_ratio_volatility operating_safety_margin \\\n", - "2393 50 0 \n", - "323 50 0 \n", - "3238 50 0 \n", - "144 50 0 \n", - "2336 50 0 \n", - "... ... ... \n", - "1703 50 0 \n", - "2441 50 0 \n", - "1054 50 0 \n", - "1488 50 0 \n", - "1619 50 0 \n", - "\n", - " net_income_ascending operating_net_cash_flow_ascending \n", - "2393 90 40 \n", - "323 90 50 \n", - "3238 90 60 \n", - "144 90 90 \n", - "2336 30 30 \n", - "... ... ... \n", - "1703 -60 -90 \n", - "2441 -90 -60 \n", - "1054 -90 -90 \n", - "1488 -90 -90 \n", - "1619 -90 -90 \n", - "\n", - "[3384 rows x 12 columns]" - ], - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
codenamescoreroe_scoreroa_scorenet_incomeassets_turnover_and_cashcollection_cash_period_and_sales_periodgross_profit_ratio_volatilityoperating_safety_marginnet_income_ascendingoperating_net_cash_flow_ascending
2393600519.SH贵州茅台95050010010050205009040
323000858.SZ五粮液91045010010050205009050
3238603688.SH石英股份85050010005005009060
144000568.SZ泸州老窖850450100050205009090
2336600438.SH通威股份8404508010050505003030
.......................................
1703300436.SZ广生堂-10000000500-60-90
2441600579.SH克劳斯-10000000500-90-60
1054002672.SZ东江环保-13000000500-90-90
1488300204.SZ舒泰神-13000000500-90-90
1619300345.SZ华民股份-13000000500-90-90
\n", - "

3384 rows × 12 columns

\n", - "
" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 16 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-14T14:25:22.482926Z", - "start_time": "2025-01-14T14:25:22.476830Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "df[:100][\"code\"]", "id": "32b5b4778985afaa", - "outputs": [ - { - "data": { - "text/plain": [ - "2393 600519.SH\n", - "323 000858.SZ\n", - "3238 603688.SH\n", - "144 000568.SZ\n", - "2336 600438.SH\n", - " ... \n", - "3318 603871.SH\n", - "2542 600702.SH\n", - "1166 002801.SZ\n", - "1227 002867.SZ\n", - "1754 300487.SZ\n", - "Name: code, Length: 100, dtype: object" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 17 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-01-13T03:17:08.882164Z", - "start_time": "2025-01-13T03:17:08.862820Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "temp_df = finance_df[finance_df[\"code\"] == \"600763.SH\"]\n", @@ -1599,357 +954,12 @@ "temp_df[[\"year\", \"roe\", \"roa\"]]" ], "id": "e6d973f4ff98ebef", - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3287426981.py:2: SettingWithCopyWarning: \n", - "A value is trying to be set on a copy of a slice from a DataFrame.\n", - "Try using .loc[row_indexer,col_indexer] = value instead\n", - "\n", - "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", - " df[\"prev_total_stockholder_interest\"] = df[\"total_stockholder_interest\"].shift(1)\n", - "/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3287426981.py:3: SettingWithCopyWarning: \n", - "A value is trying to be set on a copy of a slice from a DataFrame.\n", - "Try using .loc[row_indexer,col_indexer] = value instead\n", - "\n", - "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", - " df[\"roe\"] = df[\"net_income\"] / ((df[\"prev_total_stockholder_interest\"] + df[\"total_stockholder_interest\"]) / 2)\n", - "/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3287426981.py:4: SettingWithCopyWarning: \n", - "A value is trying to be set on a copy of a slice from a DataFrame\n", - "\n", - "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", - " df.drop(columns=[\"prev_total_stockholder_interest\"], inplace=True)\n", - "/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3105409447.py:2: SettingWithCopyWarning: \n", - "A value is trying to be set on a copy of a slice from a DataFrame.\n", - "Try using .loc[row_indexer,col_indexer] = value instead\n", - "\n", - "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", - " df[\"prev_total_assets\"] = df[\"total_assets\"].shift(1)\n", - "/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3105409447.py:3: SettingWithCopyWarning: \n", - "A value is trying to be set on a copy of a slice from a DataFrame.\n", - "Try using .loc[row_indexer,col_indexer] = value instead\n", - "\n", - "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", - " df[\"roa\"] = df[\"net_income\"] / ((df[\"prev_total_assets\"] + df[\"total_assets\"]) / 2)\n", - "/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3105409447.py:4: SettingWithCopyWarning: \n", - "A value is trying to be set on a copy of a slice from a DataFrame\n", - "\n", - "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", - " df.drop(columns=[\"prev_total_assets\"], inplace=True)\n" - ] - }, - { - "data": { - "text/plain": [ - " year roe roa\n", - "2979 2014 NaN NaN\n", - "7615 2015 0.245119 0.182412\n", - "12121 2016 0.148244 0.101560\n", - "16405 2017 0.226923 0.147172\n", - "21964 2018 0.282053 0.182929\n", - "25657 2019 0.297166 0.211903\n", - "29113 2020 0.252412 0.190406\n", - "36313 2021 0.286244 0.196068\n", - "40855 2022 0.182081 0.121805\n", - "45977 2023 0.149449 0.103658" - ], - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
yearroeroa
29792014NaNNaN
761520150.2451190.182412
1212120160.1482440.101560
1640520170.2269230.147172
2196420180.2820530.182929
2565720190.2971660.211903
2911320200.2524120.190406
3631320210.2862440.196068
4085520220.1820810.121805
4597720230.1494490.103658
\n", - "
" - ] - }, - "execution_count": 204, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 204 + "outputs": [], + "execution_count": null }, { "metadata": {}, "cell_type": "code", - "outputs": [ - { - "data": { - "text/plain": [ - " ts_code end_date roe roa\n", - "4 600763.SH 20231231 14.0666 13.4808\n", - "10 600763.SH 20221231 17.7106 15.4075\n", - "11 600763.SH 20221231 17.7106 15.4075\n", - "18 600763.SH 20211231 27.9402 24.7367\n", - "19 600763.SH 20211231 27.9402 24.7367\n", - "26 600763.SH 20201231 25.0345 24.1350\n", - "27 600763.SH 20201231 25.0345 24.1350\n", - "34 600763.SH 20191231 29.8694 27.2723\n", - "35 600763.SH 20191231 29.8694 27.2723\n", - "42 600763.SH 20181231 28.7803 23.4500\n", - "43 600763.SH 20181231 28.7803 23.4500\n", - "50 600763.SH 20171231 23.9279 18.8885\n", - "51 600763.SH 20171231 23.9279 18.8885\n", - "58 600763.SH 20161231 16.6081 13.5829\n", - "59 600763.SH 20161231 16.6081 13.5829\n", - "66 600763.SH 20151231 26.5184 22.2861\n", - "67 600763.SH 20151231 26.5184 22.2861\n", - "74 600763.SH 20141231 19.1679 20.0538\n", - "75 600763.SH 20141231 19.1679 20.0538" - ], - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ts_codeend_dateroeroa
4600763.SH2023123114.066613.4808
10600763.SH2022123117.710615.4075
11600763.SH2022123117.710615.4075
18600763.SH2021123127.940224.7367
19600763.SH2021123127.940224.7367
26600763.SH2020123125.034524.1350
27600763.SH2020123125.034524.1350
34600763.SH2019123129.869427.2723
35600763.SH2019123129.869427.2723
42600763.SH2018123128.780323.4500
43600763.SH2018123128.780323.4500
50600763.SH2017123123.927918.8885
51600763.SH2017123123.927918.8885
58600763.SH2016123116.608113.5829
59600763.SH2016123116.608113.5829
66600763.SH2015123126.518422.2861
67600763.SH2015123126.518422.2861
74600763.SH2014123119.167920.0538
75600763.SH2014123119.167920.0538
\n", - "
" - ] - }, - "execution_count": 206, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 206, "source": [ "temp_df = ts_pro.fina_indicator(\n", " ts_code=\"600763.SH\", start_date=\"20140101\", end_date=\"20241231\",\n", @@ -1960,7 +970,9 @@ "# temp_df = temp_df.drop_duplicates(subset=[\"end_date\"], keep=\"last\")\n", "temp_df" ], - "id": "b220252765677c76" + "id": "b220252765677c76", + "outputs": [], + "execution_count": null } ], "metadata": {