{"id":3873,"date":"2025-08-19T21:12:05","date_gmt":"2025-08-19T13:12:05","guid":{"rendered":"http:\/\/viplao.com\/?p=3873"},"modified":"2025-09-13T23:19:21","modified_gmt":"2025-09-13T15:19:21","slug":"%e3%80%90python%e5%ae%9e%e8%b7%b5%e6%a1%88%e4%be%8b%e3%80%91%e7%94%b5%e5%95%86%e5%b9%b3%e5%8f%b0%e6%95%b0%e6%8d%ae%e5%88%86%e6%9e%90%e5%92%8c%e6%8c%96%e6%8e%98-%e7%94%a8%e6%88%b7%e8%a1%8c%e4%b8%ba","status":"publish","type":"post","link":"http:\/\/viplao.com\/index.php\/2025\/08\/19\/%e3%80%90python%e5%ae%9e%e8%b7%b5%e6%a1%88%e4%be%8b%e3%80%91%e7%94%b5%e5%95%86%e5%b9%b3%e5%8f%b0%e6%95%b0%e6%8d%ae%e5%88%86%e6%9e%90%e5%92%8c%e6%8c%96%e6%8e%98-%e7%94%a8%e6%88%b7%e8%a1%8c%e4%b8%ba\/","title":{"rendered":"\u3010Python\u5b9e\u8df5\u6848\u4f8b\u3011\u7535\u5546\u5e73\u53f0\u6570\u636e\u5206\u6790\u548c\u6316\u6398 -\u7528\u6237\u884c\u4e3a\u5206\u6790"},"content":{"rendered":"\n<p><br>\u6211\u4eec\u7528&nbsp;<code>UserAnalyticsData<\/code>&nbsp;\u8fd9\u4e2a\u201c\u4e50\u9ad8\u5de5\u5382\u201d\u4e00\u6b21\u6027\u751f\u6210 4 \u7ec4\u6838\u5fc3\u6307\u6807\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>\u7ef4\u5ea6<\/th><th>\u79ef\u6728\u5757<\/th><th>\u4e00\u53e5\u8bdd\u5356\u70b9<\/th><\/tr><\/thead><tbody><tr><td>\u8bbe\u5907\u5206\u5e03<\/td><td>Mobile 45% \/ Desktop 30% \/ Tablet 20%<\/td><td>\u4e00\u773c\u770b\u6e05\u201c\u79fb\u52a8\u7aef\u4f18\u5148\u201d\u662f\u4e0d\u662f\u4f2a\u547d\u9898<\/td><\/tr><tr><td>\u5c0f\u65f6\/\u5468\u6d3b\u8dc3\u5ea6<\/td><td>7\u00d724 \u70ed\u529b\u56fe<\/td><td>\u5de5\u4f5c\u65e5 9-18 \u70b9\u624d\u662f\u9ec4\u91d1 9 \u5c0f\u65f6<\/td><\/tr><tr><td>\u5168\u5e74\u65e5\u5386<\/td><td>365 \u5929\u65e5\u6d3b<\/td><td>\u5468\u672b vs \u5de5\u4f5c\u65e5\uff0c\u8c01\u624d\u662f\u771f\u9ad8\u6d3b<\/td><\/tr><tr><td>\u8f6c\u5316\u6f0f\u6597<\/td><td>Homepage \u2192 Success 6 \u7ea7\u6d41\u5931<\/td><td>\u8d2d\u7269\u8f66\u5230\u652f\u4ed8\u4e0d\u5230 83%\uff0c\u94b1\u888b\u5b50\u7834\u6d1e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u4ee3\u7801\u53ea\u6709 60 \u884c\uff0c\u5374\u50cf 4 \u6761\u9ad8\u901f\u516c\u8def\uff0c\u628a\u6570\u636e\u76f4\u63a5\u5f00\u5230\u56fe\u8868\u95e8\u53e3\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>analytics_data = UserAnalyticsData(seed=42)<\/code><\/pre>\n\n\n\n<p>\u73af\u5f62\u56fe\uff1a\u638f\u7a7a\u4e2d\u5fc3\uff0c\u7559\u767d\u6697\u793a\u201c\u5176\u4ed6\u201d\u6c38\u8fdc\u53ea\u662f\u914d\u89d2\u3002<\/p>\n\n\n\n<p>\u70ed\u529b\u56fe\uff1a<code>sns.heatmap<\/code>&nbsp;\u76f4\u63a5\u6807\u6570\u5b57\uff0c\u8272\u5757\u6df1\u6d45=\u6d41\u91cf\u9ad8\u4f4e\uff0c0 \u601d\u8003\u6210\u672c\u3002<\/p>\n\n\n\n<p>\u5e74\u5386\u56fe\uff1a\u7528&nbsp;<code>calmap.yearplot<\/code>&nbsp;\u628a 365 \u5929\u538b\u6210\u4e00\u5f20\u201c\u4e8c\u7ef4\u7801\u201d\uff0c\u5468\u672b\u7ea2\u6210\u4e00\u7247\u3002<\/p>\n\n\n\n<p>\u6f0f\u6597\u56fe\uff1a\u4e0d\u7528\u7b2c\u4e09\u65b9\u5e93\uff0c\u7eaf\u624b\u5de5&nbsp;<code>matplotlib.patches.Rectangle<\/code><\/p>\n\n\n\n<p>\u8be6\u7ec6\u6848\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport calmap\nimport matplotlib.patches as patches\nfrom datetime import datetime, timedelta\n\nclass UserAnalyticsData:\n    def __init__(self, seed=42):\n        np.random.seed(seed)\n        self.generate_all_data()\n    \n    def generate_device_data(self):\n        \"\"\"\u751f\u6210\u8bbe\u5907\u4f7f\u7528\u5206\u5e03\u6570\u636e\"\"\"\n        self.devices = &#91;'Mobile', 'Desktop', 'Tablet', 'Other']\n        self.device_values = &#91;45, 30, 20, 5]\n        \n    def generate_hourly_activity(self):\n        \"\"\"\u751f\u6210\u6bcf\u5c0f\u65f6\u6d3b\u8dc3\u5ea6\u6570\u636e\"\"\"\n        self.hours = range(24)\n        self.days = &#91;'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']\n        # \u6a21\u62df\u5de5\u4f5c\u65f6\u95f4\u6bb5(9-18\u70b9)\u6d3b\u8dc3\u5ea6\u8f83\u9ad8\u7684\u60c5\u51b5\n        base_activity = np.random.randint(10, 30, size=(7, 24))\n        work_hours_boost = np.zeros((7, 24))\n        work_hours_boost&#91;:, 9:18] = np.random.randint(30, 70, size=(7, 9))\n        self.activity_data = (base_activity + work_hours_boost).astype(int)\n        \n    def generate_yearly_activity(self):\n        \"\"\"\u751f\u6210\u5168\u5e74\u6d3b\u8dc3\u5ea6\u6570\u636e\"\"\"\n        self.dates = pd.date_range('2024-01-01', '2024-12-31')\n        base_activity = np.random.randint(50, 100, len(self.dates))\n        # \u6a21\u62df\u5468\u672b\u6d3b\u8dc3\u5ea6\u8f83\u9ad8\u7684\u60c5\u51b5\n        weekend_mask = self.dates.weekday.isin(&#91;5, 6])\n        weekend_boost = np.where(weekend_mask, np.random.randint(50, 100, len(self.dates)), 0)\n        self.daily_activity = pd.Series(base_activity + weekend_boost, index=self.dates)\n        \n    def generate_user_flow(self):\n        \"\"\"\u751f\u6210\u7528\u6237\u6d41\u8f6c\u6570\u636e\"\"\"\n        self.stages = &#91;'Homepage', 'Category', 'Product', 'Cart', 'Payment', 'Success']\n        # \u6a21\u62df\u771f\u5b9e\u7684\u8f6c\u5316\u6f0f\u6597\n        initial_users = 100\n        conversion_rates = &#91;0.8, 0.5, 0.75, 0.83]  # \u5404\u9636\u6bb5\u8f6c\u5316\u7387\n        self.flow_values = &#91;initial_users]\n        current_users = initial_users\n        for rate in conversion_rates:\n            current_users = int(current_users * rate)\n            self.flow_values.append(current_users)\n            \n    def generate_all_data(self):\n        \"\"\"\u751f\u6210\u6240\u6709\u9700\u8981\u7684\u6570\u636e\"\"\"\n        self.generate_device_data()\n        self.generate_hourly_activity()\n        self.generate_yearly_activity()\n        self.generate_user_flow()\n\nclass UserAnalyticsVisualizer:\n    def __init__(self, data):\n        self.data = data\n        \n    def setup_plot_style(self):\n        \"\"\"\u8bbe\u7f6e\u7ed8\u56fe\u6837\u5f0f\"\"\"\n        plt.figure(figsize=(20, 15))\n        plt.rcParams&#91;'figure.facecolor'] = 'white'\n        plt.rcParams&#91;'axes.facecolor'] = 'white'\n        plt.rcParams&#91;'grid.color'] = 'gray'\n        plt.rcParams&#91;'grid.linestyle'] = '--'\n        plt.rcParams&#91;'font.sans-serif'] = &#91;'SimHei']  # \u4f7f\u7528\u9ed1\u4f53\n        plt.rcParams&#91;'axes.unicode_minus'] = False  # \u5904\u7406\u8d1f\u53f7\u663e\u793a\n        \n    def plot_device_distribution(self, ax):\n        \"\"\"\u7ed8\u5236\u8bbe\u5907\u5206\u5e03\u73af\u5f62\u56fe\"\"\"\n        plt.sca(ax)\n        plt.pie(self.data.device_values, labels=self.data.devices, \n                autopct='%1.1f%%', pctdistance=0.85,\n                wedgeprops=dict(width=0.5))\n        plt.title('\u8bbe\u5907\u5206\u5e03\u73af\u5f62\u56fe')\n        \n    def plot_activity_heatmap(self, ax):\n        \"\"\"\u7ed8\u5236\u6d3b\u8dc3\u5ea6\u70ed\u529b\u56fe\"\"\"\n        plt.sca(ax)\n        sns.heatmap(self.data.activity_data, \n                    xticklabels=self.data.hours,\n                    yticklabels=self.data.days,\n                    cmap='YlOrRd', \n                    annot=True, \n                    fmt='d')  # \u4f7f\u7528'd'\u56e0\u4e3a\u6570\u636e\u5df2\u7ecf\u8f6c\u6362\u4e3a\u6574\u6570\n        plt.title('\u6d3b\u8dc3\u5ea6\u70ed\u529b\u56fe')\n        \n    def plot_yearly_calendar(self, ax):\n        \"\"\"\u7ed8\u5236\u5e74\u5ea6\u65e5\u5386\u56fe\"\"\"\n        plt.sca(ax)\n        calmap.yearplot(self.data.daily_activity, \n                       year=2024, \n                       cmap='YlOrRd',\n                       fillcolor='lightgrey', \n                       daylabels='MTWTFSS')\n        plt.title('\u5e74\u5ea6\u65e5\u5386\u56fe (2024)')\n        \n    def draw_flow(self, ax, x, y, width, height, color):\n        \"\"\"\u7ed8\u5236\u6d41\u52a8\u6548\u679c\u8f85\u52a9\u51fd\u6570\"\"\"\n        rect = patches.Rectangle((x, y), width, height, \n                               facecolor=color, alpha=0.6)\n        ax.add_patch(rect)\n        \n    def plot_user_flow(self, ax):\n        \"\"\"\u7ed8\u5236\u7528\u6237\u6d41\u8f6c\u56fe\"\"\"\n        plt.sca(ax)\n        colors = plt.cm.Oranges(np.linspace(0.3, 0.9, len(self.data.stages)))\n        y_positions = np.linspace(0.2, 0.8, len(self.data.stages))\n        \n        for i in range(len(self.data.flow_values)):\n            self.draw_flow(ax, i*0.15, y_positions&#91;i], 0.1, \n                         self.data.flow_values&#91;i]\/200, colors&#91;i])\n            plt.text(i*0.15-0.02, y_positions&#91;i], \n                    self.data.stages&#91;i], rotation=45)\n            if i &lt; len(self.data.flow_values):\n                plt.text(i*0.15+0.05, y_positions&#91;i]+self.data.flow_values&#91;i]\/400, \n                        str(self.data.flow_values&#91;i]))\n        \n        ax.set_xlim(-0.1, 1)\n        ax.set_ylim(0, 1)\n        ax.axis('off')\n        plt.title('\u7528\u6237\u6d41\u8f6c\u56fe')\n        \n    def create_visualization(self):\n        \"\"\"\u521b\u5efa\u6240\u6709\u53ef\u89c6\u5316\u56fe\u8868\"\"\"\n        self.setup_plot_style()\n        \n        # \u521b\u5efa\u5b50\u56fe\n        ax1 = plt.subplot(221)\n        ax2 = plt.subplot(222)\n        ax3 = plt.subplot(223)\n        ax4 = plt.subplot(224)\n        \n        # \u7ed8\u5236\u5404\u4e2a\u56fe\u8868\n        self.plot_device_distribution(ax1)\n        self.plot_activity_heatmap(ax2)\n        self.plot_yearly_calendar(ax3)\n        self.plot_user_flow(ax4)\n        \n        plt.tight_layout()\n        plt.show()\n        \n    def generate_report(self):\n        \"\"\"\u751f\u6210\u6570\u636e\u5206\u6790\u62a5\u544a\"\"\"\n        print(\"\\n\u6570\u636e\u5206\u6790\u62a5\u544a:\")\n        print(\"1. \u8bbe\u5907\u4f7f\u7528\u5206\u5e03:\")\n        print(f\"   - \u79fb\u52a8\u7aef\u7528\u6237\u5360\u6bd4\u6700\u9ad8\uff0c\u8fbe\u5230{self.data.device_values&#91;0]}%\")\n        print(f\"   - \u684c\u9762\u7aef\u6b21\u4e4b\uff0c\u5360{self.data.device_values&#91;1]}%\")\n        \n        print(\"\\n2. \u7528\u6237\u6d3b\u8dc3\u65f6\u95f4\u5206\u6790:\")\n        print(\"   - \u5de5\u4f5c\u65e5\u6d3b\u8dc3\u5ea6\u9ad8\u4e8e\u5468\u672b\")\n        print(\"   - \u9ad8\u5cf0\u65f6\u6bb5\u96c6\u4e2d\u57289:00-18:00\")\n        \n        print(\"\\n3. \u5168\u5e74\u6d3b\u8dc3\u5ea6\u5206\u6790:\")\n        print(f\"   - \u5e73\u5747\u65e5\u6d3b\u8dc3\u7528\u6237\u6570: {self.data.daily_activity.mean():.0f}\")\n        print(f\"   - \u6700\u9ad8\u65e5\u6d3b\u8dc3\u7528\u6237\u6570: {self.data.daily_activity.max()}\")\n        \n        print(\"\\n4. \u7528\u6237\u884c\u4e3a\u6d41\u8f6c:\")\n        conversion_rate = (self.data.flow_values&#91;-1] \/ self.data.flow_values&#91;0]) * 100\n        cart_to_payment = (self.data.flow_values&#91;-2] \/ self.data.flow_values&#91;-3]) * 100\n        print(f\"   - \u4ece\u9996\u9875\u5230\u6210\u529f\u652f\u4ed8\u7684\u8f6c\u5316\u7387\u7ea6\u4e3a{conversion_rate:.1f}%\")\n        print(f\"   - \u8d2d\u7269\u8f66\u5230\u652f\u4ed8\u73af\u8282\u7684\u8f6c\u5316\u7387\u4e3a{cart_to_payment:.1f}%\")\n\n# \u4f7f\u7528\u793a\u4f8b\nif __name__ == \"__main__\":\n    # \u751f\u6210\u6570\u636e\n    analytics_data = UserAnalyticsData(seed=42)\n    \n    # \u521b\u5efa\u53ef\u89c6\u5316\u5668\u5e76\u5c55\u793a\u7ed3\u679c\n    visualizer = UserAnalyticsVisualizer(analytics_data)\n    visualizer.create_visualization()\n    visualizer.generate_report()<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u6211\u4eec\u7528&nbsp;UserAnalyticsData&nbsp;\u8fd9\u4e2a\u201c\u4e50\u9ad8\u5de5\u5382\u201d\u4e00\u6b21\u6027\u751f\u6210 4 \u7ec4\u6838&hellip; <a href=\"http:\/\/viplao.com\/index.php\/2025\/08\/19\/%e3%80%90python%e5%ae%9e%e8%b7%b5%e6%a1%88%e4%be%8b%e3%80%91%e7%94%b5%e5%95%86%e5%b9%b3%e5%8f%b0%e6%95%b0%e6%8d%ae%e5%88%86%e6%9e%90%e5%92%8c%e6%8c%96%e6%8e%98-%e7%94%a8%e6%88%b7%e8%a1%8c%e4%b8%ba\/\" class=\"more-link read-more\" rel=\"bookmark\">\u7ee7\u7eed\u9605\u8bfb <span class=\"screen-reader-text\">\u3010Python\u5b9e\u8df5\u6848\u4f8b\u3011\u7535\u5546\u5e73\u53f0\u6570\u636e\u5206\u6790\u548c\u6316\u6398 -\u7528\u6237\u884c\u4e3a\u5206\u6790<\/span><i class=\"fa fa-arrow-right\"><\/i><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[28],"views":789,"_links":{"self":[{"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/posts\/3873"}],"collection":[{"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/comments?post=3873"}],"version-history":[{"count":2,"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/posts\/3873\/revisions"}],"predecessor-version":[{"id":3915,"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/posts\/3873\/revisions\/3915"}],"wp:attachment":[{"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/media?parent=3873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/categories?post=3873"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/viplao.com\/index.php\/wp-json\/wp\/v2\/tags?post=3873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}