• [区域初赛赛题问题] runtime error
    在demo基础上修改,且本地运行测试样例没有问题,提交报runtime error,这是什么错误,能展示报错的细节吗
  • sleep10秒得到一样的成绩是咋回事?
    线上判题器对时延的敏感性到底如何?10s的时间不改变成绩嘛?
  • [区域初赛赛题问题] 交demo是多少分?
    想问一下各位py,c++,java交demo分别多少分啊,一样吗?
  • [交流吐槽] 在 CodeArts 的 AI 聊天框中:添加了图片或引用上下文 点击发送后,图片/引用没有被清空,还留在输入框中
    现象: 在 CodeArts 的 AI 聊天框中:添加了图片或引用上下文点击发送后,图片/引用没有被清空,还留在输入框中
  • [区域初赛赛题问题] 导入numpy后,线上测评就报错?
    同样的代码,在没有导入numpy时线上测评可正常输出分数。但是导入numpy后就报错,wrong answer。
  • python -1 wrong answer
    python -1 wrong answer是哪里出了问题,手册的报错都是0
  • [区域初赛赛题问题] 编译错误能否返回报错信息
    本地可以编译的情况下排查起来真的很费时间
  • [问题求助] http://localhost:5000/和Flask服务
    基于码道生成了好几个Python编码的项目文件,在码道环境中的浏览器是否每一次都要启动Flask服务才能通过http://localhost:5000/路由文件?在Python进程和Flask服务正常工作下,在本地浏览器中输入http://localhost:5000/,路由怎么知道是访问那个码道生成的项目文件和通过路由启动运行? 
  • huaweicloud-cli的安装
    python 环境下huaweicloud-cli怎么安装?huaweicloudsdkcore:已成功安装python -m pip list | findstr "huaweicloud"huaweicloudsdkcore      3.1.187huaweicloud-cli:安装未成功python -m pip install --upgrade huaweicloud-cli -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cnLooking in indexes: https://pypi.tuna.tsinghua.edu.cn/simpleERROR: Could not find a version that satisfies the requirement huaweicloud-cli (from versions: none)ERROR: No matching distribution found for huaweicloud-cli请问:“huaweicloud-cli:安装未成功”怎么解决?
  • [交流吐槽] 越来越卡
    用了一周了,一天比一天卡啊,提个问题有时候要等10多分钟,怎么办呀?是用的人太多了,还是不够智能要算的太多了,赶紧加快速度呀!!!
  • [技术干货] 2月技术干货合集来啦~
    1、PyCharm安装Python时的常见pip报错原因与解决方案全解析【转载】cid:link_02、Python中修复中文乱码的7种场景方法介绍【转载】cid:link_13、深入解析Python命名空间与作用域的核心机制【转载】cid:link_24、Git忽略大小写(重命名文件)的解决办法【转载】cid:link_35、git push常见问题及解决方案【转载】cid:link_46、一文详解Git的暂存与stash功能【转载】cid:link_57、Git合并后回退操作的完整指南【转载】cid:link_68、在鸿蒙上使用webview_flutter包的详细示例【转载】cid:link_79、一些常见的Git分支命名策略和实践指南【转载】cid:link_810、Java中函数式接口实现分布式锁【转载】cid:link_911、SpringBoot对接第三方系统的实现【转载】cid:link_1012、SpringBoot注解实现网络限速【转载】cid:link_1113、浅谈Java 线程池线程数怎么定【转载】cid:link_1214、MySQL中GTID 模式的使用【转载】https://bbs.huaweicloud.com/forum/thread-0212720697012681216-1-1.html
  • [技术干货] 深入解析Python命名空间与作用域的核心机制【转载】
    一、 什么是命名空间?从字典到代码世界在 Python 中,**命名空间(Namespace)**本质上是一个从名字到对象的映射。这听起来很抽象,但如果你熟悉 Python 的字典(Dictionary),理解起来就非常容易了。1.1 命名空间的“字典”本质想象一下,你在操作一个巨大的字典,字典的键(Key)是你定义的变量名、函数名或类名,而值(Value)则是这些名字所指向的内存对象。例如,当你写下以下代码时:1234name = "Alice"age = 25def say_hello():    print("Hello")Python 解释器就在内存中创建了一个命名空间(通常称为全局命名空间),它看起来就像这样:12345{    'name': 'Alice',     'age': 25,     'say_hello': <function say_hello at 0x...>}1.2 命名空间的种类Python 解释器在运行时会同时维护多个命名空间,它们互不干扰,各自独立。主要分为以下三种:内置命名空间 (Built-in Namespace):存放 Python 的内置函数和异常(如 print()、len()、Exception)。生命周期:Python 解释器启动时创建,解释器关闭时销毁。它是永生的。全局命名空间 (Global Namespace):存放模块(.py 文件)级别定义的变量、函数和类。生命周期:模块被导入(import)时创建,解释器退出时销毁。每个模块拥有独立的全局命名空间。局部命名空间 (Local Namespace):存放函数或类方法内部定义的变量和参数。生命周期:函数被调用时创建,函数执行结束或抛出异常时销毁。案例演示:123456789101112131415import builtins # 1. 检查内置命名空间print("len" in dir(builtins))  # True # 2. 全局命名空间global_var = "我是全局的" def func():    # 3. 局部命名空间    local_var = "我是局部的"    print(local_var) func()# print(local_var) # 报错 NameError,局部变量无法在外部访问二、 作用域:名字查找的“寻宝地图”如果说命名空间是存放宝藏(对象)的独立仓库,那么**作用域(Scope)**就是连接你手中的代码与这些仓库的“寻宝地图”。作用域定义了在程序的哪一部分可以访问到哪个命名空间中的名字。2.1 LEGB 规则:查找名字的顺序当你在代码中引用一个变量名(比如 x)时,Python 会按照 LEGB 的顺序依次在这些命名空间中进行查找:L (Local): 首先查找局部命名空间(当前函数内部)。E (Enclosing): 如果局部找不到,查找嵌套作用域(闭包函数的外层函数)。G (Global): 如果嵌套作用域也找不到,查找全局命名空间(当前模块)。B (Built-in): 如果全局也找不到,查找内置命名空间。一旦找到,Python 就立即停止搜索并返回对应的值;如果最终都找不到,则抛出 NameError。2.2 实战案例:LEGB 的真实表现让我们通过一个具体的例子来看看 LEGB 规则是如何运作的:1234567891011121314x = "全局变量 (G)" def outer():    x = "外层变量 (E)"         def inner():        x = "局部变量 (L)"        print("Inner:", x) # 查找 L,找到 "局部变量 (L)"     inner()    print("Outer:", x) # 查找 L,没找到(inner 已经结束),查找 E,找到 "外层变量 (E)" outer()print("Global:", x) # 查找 L -> 查找 E -> 查找 G,找到 "全局变量 (G)"输出结果:Inner: 局部变量 (L)Outer: 外层变量 (E)Global: 全局变量 (G)这个例子完美展示了 Python 如何在不同的作用域层级中查找变量。三、 关键陷阱与进阶技巧理解了基础概念后,我们来看看在实际开发(尤其是 OOP 和脚本开发)中,命名空间和作用域经常会带来的陷阱以及解决方案。3.1global与nonlocal:打破作用域的封印默认情况下,你只能在局部作用域读取全局变量,但不能修改它。如果你需要在函数内部修改全局变量,必须使用 global 关键字。12345678counter = 0 def increment():    global counter  # 声明使用全局命名空间中的 counter    counter += 1 increment()print(counter) # 输出 1而在嵌套函数中,如果你想在内层函数修改外层函数的变量,则需要使用 nonlocal。123456789def outer():    count = 0    def inner():        nonlocal count # 声明使用外层(非全局)作用域的 count        count += 1    inner()    print(count) # 输出 1 outer()注意:滥用 global 和 nonlocal 会破坏代码的封装性,导致逻辑耦合,应尽量通过函数参数传递数据。3.2 类与对象:属性的查找顺序在 OOP(面向对象编程)中,类本身也维护着一个命名空间(类属性),而每个实例对象也有自己的命名空间(实例属性)。当访问 self.attr 时,Python 的查找顺序是:实例命名空间(self.__dict__)类命名空间(cls.__dict__)父类命名空间(继承链)AttributeError案例:类属性的陷阱1234567891011121314151617class Dog:    tricks = []  # 类属性(共享)     def __init__(self, name):        self.name = name     def add_trick(self, trick):        self.tricks.append(trick) d1 = Dog('Fido')d2 = Dog('Buddy') d1.add_trick('roll over')d2.add_trick('play dead') print(d1.tricks) # 输出 ['roll over', 'play dead']# 糟糕!两只狗的列表混在一起了,因为它们共享同一个类命名空间下的 tricks 列表修正方案:通常实例属性应该在 __init__ 中定义。1234567class Dog:    def __init__(self, name):        self.name = name        self.tricks = [] # 每个实例独立的命名空间     def add_trick(self, trick):        self.tricks.append(trick)3.3__slots__:优化对象的命名空间Python 的对象属性通常存储在 __dict__ 字典中,这虽然灵活但消耗内存。在高性能脚本开发或大规模对象创建场景下,我们可以使用 __slots__ 来显式定义对象允许拥有的属性。这实际上是将对象的命名空间从动态的字典变成了静态的结构体,从而节省内存并加速属性访问。123456789class Point:    __slots__ = ('x', 'y') # 明确声明属性,不再使用 __dict__     def __init__(self, x, y):        self.x = x        self.y = y p = Point(1, 2)# p.z = 3  # 抛出 AttributeError,因为 z 不在 __slots__ 定义的命名空间中四、 总结与最佳实践掌握 Python 的命名空间与作用域,不仅仅是为了应付面试,更是为了写出逻辑清晰、易于维护的代码。核心要点回顾:命名空间是独立的:不同模块、函数、类拥有独立的命名空间,互不干扰。LEGB 是铁律:理解查找顺序能帮你解决绝大多数 NameError 和逻辑错误。避免命名冲突:不要在全局作用域定义与内置函数同名的变量(例如 list = [1, 2, 3] 会覆盖内置的 list)。最小化全局变量:尽量使用参数传递和返回值来共享数据,减少对全局命名空间的依赖。
  • [技术干货] Python导包、分包与打包的完整教程【转载】
    第一部分:Python导包基础(完全新手友好)第一章:理解Python中的“包”和“模块”1.1 什么是模块?12345678# 一个.py文件就是一个模块# example.py 就是一个名为example的模块def say_hello():    print("你好!")  def add(a, b):    return a + b1.2 什么是包?12345# 包是一个包含__init__.py文件的文件夹my_package/    __init__.py    # 这个文件让Python知道这是包    module1.py    module2.py第二章:最简单的导包方式2.1 同一个文件夹内的导入1234项目结构:project/    main.py    utils.py1234567# utils.pydef greet(name):    return f"你好,{name}!"  def calculate_sum(numbers):    return sum(numbers)12345678# main.py - 方法1:导入整个模块import utils result = utils.greet("小明")print(result)  # 输出:你好,小明! total = utils.calculate_sum([1, 2, 3, 4, 5])print(total)   # 输出:1512345# main.py - 方法2:导入特定功能from utils import greet, calculate_sum result = greet("小红")  # 直接使用,不用加 utils.print(result)1234# main.py - 方法3:导入并重命名from utils import greet as say_hello say_hello("小张")  # 使用新名字2.2 导入外部库12345678# Python内置库import mathimport randomimport datetime # 第三方库(需要先安装)# pip install requestsimport requests第三章:理解绝对导入和相对导入3.1 创建多级目录结构123456789101112my_project/│   main.py│├───database/│   │   __init__.py│   │   connector.py│   │   models.py│└───utils/    │   __init__.py    │   math_tools.py    │   string_tools.py3.2 绝对导入(推荐新手使用)1234# main.pyfrom database.connector import connect_dbfrom utils.math_tools import add_numbersfrom utils.string_tools import format_text3.3 相对导入(在包内部使用) 若直接运行的是models.py123# 在 database/models.py 中from .connector import connect_db    # . 表示同一目录from ..utils.math_tools import add_numbers  # .. 表示上级目录若直接运行的是main.py123# 在 database/models.py 中from database.connector import connect_db    # 与main同一目录from utils.math_tools import add_numbers  # 与main同一目录第四章:init.py 文件的妙用4.1 最简单的 init.py12# database/__init__.py# 空文件也可以,但有它才算是包4.2 有组织的 init.py12345678# utils/__init__.py# 集中导入,方便外部使用from .math_tools import *from .string_tools import *  # 或者更精确的控制__all__ = ['add_numbers', 'multiply_numbers', 'format_text']12# 这样在外面就可以from utils import add_numbers  # 不需要知道math_tools的存在4.3 包级别的变量和初始化123456789101112131415# utils/__init__.py# 包版本信息__version__ = "1.0.0"__author__ = "你的名字"  # 包初始化代码print("正在加载工具包...")  # 包级别的配置DEFAULT_CONFIG = {    "log_level": "INFO",    "timeout": 30}第二部分:项目分包实践(结构化思维)第五章:从小项目到中大型项目的演变5.1 初级阶段:扁平结构12345simple_app/    app.py          # 主程序    config.py       # 配置    helpers.py      # 辅助函数    data.json       # 数据文件5.2 中级阶段:按功能分包123456789101112131415161718192021222324medium_app/│   main.py                    # 程序入口│   requirements.txt           # 依赖列表│   README.md                 # 说明文档│├───core/                     # 核心业务逻辑│   │   __init__.py│   │   calculator.py        # 计算器类│   │   validator.py         # 验证器│├───ui/                       # 用户界面│   │   __init__.py│   │   window.py           # 主窗口│   │   widgets.py          # 小部件│├───data/                     # 数据处理│   │   __init__.py│   │   loader.py           # 数据加载│   │   saver.py            # 数据保存│└───utils/                   # 通用工具    │   __init__.py    │   logger.py           # 日志工具    │   formatter.py        # 格式化工具5.3 专业阶段:标准Python项目结构123456789101112131415161718192021222324252627282930313233343536373839404142434445464748professional_app/│├───src/                     # 源代码目录(推荐结构)│   └───my_app/              # 你的包名│       │   __init__.py│       │   __main__.py     # 命令行入口:python -m my_app│       │   cli.py          # CLI接口│       │   config.py       # 配置管理│       ││       ├───core/│       │   │   __init__.py│       │   │   business_logic.py│       │   │   models.py│       ││       ├───api/│       │   │   __init__.py│       │   │   routes.py│       │   │   handlers.py│       ││       └───utils/│           │   __init__.py│           │   helpers.py│           │   decorators.py│├───tests/                   # 测试目录│   │   __init__.py│   │   test_core.py│   │   test_utils.py│   │   conftest.py         # pytest配置│├───docs/                    # 文档│       index.md│       tutorial.md│├───examples/               # 示例代码│       basic_usage.py│       advanced_features.py│├───scripts/                # 脚本│       setup_env.py│       generate_data.py││   .gitignore              # Git忽略文件│   pyproject.toml          # 项目配置(现代方式)│   setup.py               # 安装配置(传统方式)│   README.md              # 项目说明│   LICENSE               # 许可证└───requirements.txt       # 依赖包列表第三部分:打包成可执行文件(无需Python环境运行)第七章:为什么需要打包成exe?7.1 打包的好处用户无需安装Python可以直接双击运行保护源代码(可选)方便分发第八章:使用PyInstaller(最简单、最流行)8.1 安装PyInstaller123456# 在命令行中执行pip install pyinstaller  # 验证安装pyinstaller --version8.2 基本打包命令12345# 最简单的打包pyinstaller your_program.py  # 打包后,在 dist/ 文件夹中找到可执行文件8.3 常用参数详解12345678910111213141516171819202122232425# 1. --onefile:打包成单个文件pyinstaller --onefile main.py  # 2. --windowed:无控制台窗口(适合GUI程序)pyinstaller --windowed gui_app.py  # 3. --icon:设置图标pyinstaller --onefile --windowed --icon=my_icon.ico main.py  # 4. --name:指定输出文件名pyinstaller --name "我的应用" main.py  # 5. --add-data:添加额外文件(如配置文件、图片)# Windows格式:源文件路径;目标路径# Linux/Mac格式:源文件路径:目标路径pyinstaller --add-data "config.ini;." main.pypyinstaller --add-data "images/*.png:images" main.py  # 6. --hidden-import:添加隐藏的依赖pyinstaller --hidden-import=tkinter main.py8.4 实战:打包一个图形界面程序12345678910111213# 假设你有一个 tkinter 程序pip install pyinstaller  # 进入项目目录cd your_project_folder  # 打包命令pyinstaller --onefile --windowed --icon=app.ico --name "我的应用" ^            --add-data "images;images" ^            --add-data "config.ini;." ^            main.py第九章:使用spec文件进行高级控制9.1 生成spec文件12345# 生成初始spec文件pyi-makespec main.py  # 或者从已经打包的项目中复制9.2 spec文件详解1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162# main.spec# -*- mode: python ; coding: utf-8 -*-  a = Analysis(    ['main.py'],  # 主程序文件    pathex=[],    # 搜索路径    binaries=[],  # 二进制文件    datas=[       # 数据文件        ('config.ini', '.'),        ('images/*.png', 'images'),        ('sounds/*.wav', 'sounds')    ],    hiddenimports=[  # 隐藏的依赖        'tkinter',        'PIL._tkinter_finder'    ],    hookspath=[],    # 钩子路径    hooksconfig={},  # 钩子配置    runtime_hooks=[],  # 运行时钩子    excludes=[],     # 排除模块(减少体积)    win_no_prefer_redirects=False,    win_private_assemblies=False,    cipher=None,     # 加密字节码    noarchive=False  # 不打包成archive)  # 打包成单个文件pyz = PYZ(a.pure, a.zipped_data, cipher=None)  exe = EXE(    pyz,    a.scripts,    [],    exclude_binaries=True,    name='我的应用',  # 输出文件名    debug=False,    bootloader_ignore_signals=False,    strip=False,    upx=True,        # 使用UPX压缩    console=False,   # 显示控制台?True/False    icon='app.ico',  # 图标    disable_windowed_traceback=False,    argv_emulation=False,    target_arch=None,    codesign_identity=None,    entitlements_file=None)  coll = COLLECT(    exe,    a.binaries,    a.zipfiles,    a.datas,    strip=False,    upx=True,    upx_exclude=[],    name='我的应用'  # 文件夹名称)9.3 使用spec文件打包12# 使用spec文件打包pyinstaller main.spec第十章:使用cx_Freeze(跨平台替代方案)10.1 安装和基本使用1pip install cx-Freeze最佳实践指南使用src布局:将源代码放在src目录下清晰的分层:按功能而不是按类型组织最小化import:只导入需要的模块使用__init__.py控制导出:明确公开的API虚拟环境:在干净的虚拟环境中打包测试打包结果:在另一台干净电脑上测试版本控制:每次打包使用不同的版本号签名和加密:商业应用考虑代码签名
  • [互动交流] 无法安装Scikit-learn库😭
    终端执行pip install scikit-learn,下载后安装过程中报错,有没大神能帮忙看一下🙏系统是鸿蒙6.0.0.130,错误信息如下:Collecting scikit-learn Using cached scikit_learn-1.8.0.tar.gz (7.3 MB) Installing build dependencies ... error error: subprocess-exited-with-error × installing build dependencies for scikit-learn did not run successfully. │ exit code: 1 ╰─> [64 lines of output] Collecting meson-python<0.19.0,>=0.17.1 Using cached meson_python-0.18.0-py3-none-any.whl.metadata (2.8 kB) Collecting cython<3.3.0,>=3.1.2 Using cached cython-3.2.4-py3-none-any.whl.metadata (7.3 kB) Collecting numpy<2.4.0,>=2 Using cached numpy-2.3.5.tar.gz (20.6 MB) Installing build dependencies: started Installing build dependencies: finished with status 'done' Getting requirements to build wheel: started Getting requirements to build wheel: finished with status 'done' Installing backend dependencies: started Installing backend dependencies: finished with status 'error' error: subprocess-exited-with-error × installing backend dependencies for numpy did not run successfully. │ exit code: 1 ╰─> [43 lines of output] Collecting patchelf>=0.11.0 Using cached patchelf-0.17.2.4.tar.gz (149 kB) Installing build dependencies: started Installing build dependencies: finished with status 'done' Getting requirements to build wheel: started Getting requirements to build wheel: finished with status 'done' Installing backend dependencies: started Installing backend dependencies: finished with status 'done' Preparing metadata (pyproject.toml): started Preparing metadata (pyproject.toml): finished with status 'done' Building wheels for collected packages: patchelf Building wheel for patchelf (pyproject.toml): started Building wheel for patchelf (pyproject.toml): finished with status 'error' error: subprocess-exited-with-error × Building wheel for patchelf (pyproject.toml) did not run successfully. │ exit code: 1 ╰─> [16 lines of output] *** scikit-build-core 0.11.6 using CMake 3.28.2 (wheel) *** Configuring CMake... loading initial cache file build/py3-none-harmonyos_aarch64/CMakeInit.txt CMake Error at /data/app/cmake.org/cmake_3.28.2/share/cmake-3.28/Modules/CMakeDetermineCCompiler.cmake:49 (message): Could not find compiler set in environment variable CC: cc. Call Stack (most recent call first): CMakeLists.txt:3 (project) CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage -- Configuring incomplete, errors occurred! *** CMake configuration failed [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for patchelf Failed to build patchelf error: failed-wheel-build-for-install × Failed to build installable wheels for some pyproject.toml based projects ╰─> patchelf [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed to build 'numpy' when installing backend dependencies for numpy [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed to build 'scikit-learn' when installing build dependencies for scikit-learn
  • [技术干货] Python数据分析实战——基于Pandas与Matplotlib的电商用户行为分析
    在大数据时代,数据分析已成为企业决策的核心支撑,Python凭借其丰富的数据分析库(Pandas、NumPy、Matplotlib等),成为数据分析领域的首选语言。电商平台积累了海量的用户行为数据(浏览、收藏、加购、购买等),通过对这些数据的分析,可挖掘用户消费习惯、优化产品布局、提升营销效果。本文将基于真实电商用户行为数据集,使用Pandas进行数据清洗、处理与分析,结合Matplotlib进行数据可视化,完成用户行为全流程分析,输出可落地的分析报告与业务建议,包含完整代码与详细分析过程。一、核心技术栈与数据集介绍1. 技术栈选型核心库:Pandas 2.1.x(数据处理与分析)、NumPy 1.26.x(数值计算)、Matplotlib 3.8.x(数据可视化)、Seaborn 0.13.x(美化图表);开发环境:Python 3.9+、Jupyter Notebook(便于交互式分析)、Anaconda(环境管理)。2. 数据集介绍本文使用的电商用户行为数据集来源于某电商平台,包含2024年1月1日至1月31日的用户行为数据,共100万条记录,字段说明如下:字段名称字段说明数据类型取值范围user_id用户唯一标识整数无重复,唯一标识用户item_id商品唯一标识整数无重复,唯一标识商品category_id商品类别ID整数同一类别商品对应同一IDbehavior_type用户行为类型字符串view(浏览)、collect(收藏)、cart(加购)、buy(购买)timestamp行为发生时间戳整数Unix时间戳(秒)二、数据预处理(数据清洗)数据预处理是数据分析的基础,主要包括数据加载、缺失值处理、重复值处理、异常值处理、数据类型转换等步骤,确保数据的准确性与可用性。1. 数据加载与初步探索 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from datetime import datetime import warnings warnings.filterwarnings('ignore') # 设置中文字体(解决Matplotlib中文显示问题) plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans'] plt.rcParams['axes.unicode_minus'] = False # 加载数据集(CSV格式) df = pd.read_csv('user_behavior_data.csv') # 初步探索数据 print("数据集形状(行数,列数):", df.shape) print("\n数据集前5行:") print(df.head()) print("\n数据集基本信息:") print(df.info()) print("\n数据集描述性统计:") print(df.describe()) print("\n缺失值统计:") print(df.isnull().sum()) print("\n重复值统计:") print(df.duplicated().sum()) print("\n用户行为类型分布:") print(df['behavior_type'].value_counts()) 初步探索结果分析:数据集共100万行、5列,无缺失值,存在238条重复记录,用户行为类型包括view(75万条)、cart(15万条)、collect(8万条)、buy(2万条),符合电商用户“浏览多、购买少”的行为特征。2. 数据清洗 # 1. 处理重复值(删除重复记录) df = df.drop_duplicates() print(f"删除重复值后数据集形状:{df.shape}") # 2. 处理时间戳(转换为datetime格式,提取日期、小时等信息) df['datetime'] = pd.to_datetime(df['timestamp'], unit='s') df['date'] = df['datetime'].dt.date df['hour'] = df['datetime'].dt.hour df['weekday'] = df['datetime'].dt.weekday # 0表示周一,6表示周日 # 3. 异常值处理(检查用户ID、商品ID等字段是否合理,此处假设无异常值,可根据实际情况扩展) # 检查时间范围是否在2024年1月 df['year_month'] = df['datetime'].dt.strftime('%Y-%m') print(f"数据时间范围:{df['date'].min()} 至 {df['date'].max()}") print(f"时间范围分布:{df['year_month'].value_counts()}") # 4. 重置索引 df = df.reset_index(drop=True) # 清洗后数据预览 print("\n清洗后数据集前5行:") print(df.head()) print("\n清洗后数据集信息:") print(df.info()) 数据清洗完成后,数据集剩余999762条记录,新增了datetime、date、hour、weekday等时间相关字段,便于后续按时间维度分析用户行为。三、核心数据分析与可视化本次分析围绕用户行为全流程展开,核心分析维度包括:用户行为转化分析、时间维度行为分析、商品类别分析、用户价值分析,通过数据可视化直观呈现分析结果。1. 用户行为转化分析用户行为转化是电商分析的核心指标,主要关注从浏览到购买的全链路转化效率,计算各环节转化率(收藏率、加购率、购买率),识别转化瓶颈。 # 1. 计算各行为类型用户数(去重) user_behavior = df.groupby('behavior_type')['user_id'].nunique().reset_index() user_behavior.columns = ['behavior_type', 'user_count'] print("各行为类型用户数:") print(user_behavior) # 2. 计算各行为类型商品数(去重) item_behavior = df.groupby('behavior_type')['item_id'].nunique().reset_index() item_behavior.columns = ['behavior_type', 'item_count'] print("\n各行为类型商品数:") print(item_behavior) # 3. 计算转化漏斗(基于用户行为序列) # 首先获取有浏览行为的用户 view_users = df[df['behavior_type'] == 'view']['user_id'].unique() print(f"\n有浏览行为的用户数:{len(view_users)}") # 浏览→收藏转化率(有浏览且有收藏的用户数 / 有浏览行为的用户数) collect_users = df[df['behavior_type'] == 'collect']['user_id'].unique() view_collect_users = set(view_users) & set(collect_users) view_collect_rate = len(view_collect_users) / len(view_users) * 100 # 浏览→加购转化率 cart_users = df[df['behavior_type'] == 'cart']['user_id'].unique() view_cart_users = set(view_users) & set(cart_users) view_cart_rate = len(view_cart_users) / len(view_users) * 100 # 浏览→购买转化率 buy_users = df[df['behavior_type'] == 'buy']['user_id'].unique() view_buy_rate = len(buy_users) / len(view_users) * 100 # 收藏→购买转化率(有收藏且有购买的用户数 / 有收藏行为的用户数) collect_buy_users = set(collect_users) & set(buy_users) collect_buy_rate = len(collect_buy_users) / len(collect_users) * 100 # 加购→购买转化率 cart_buy_users = set(cart_users) & set(buy_users) cart_buy_rate = len(cart_buy_users) / len(cart_users) * 100 # 输出转化率 print(f"\n用户行为转化率:") print(f"浏览→收藏转化率:{view_collect_rate:.2f}%") print(f"浏览→加购转化率:{view_cart_rate:.2f}%") print(f"浏览→购买转化率:{view_buy_rate:.2f}%") print(f"收藏→购买转化率:{collect_buy_rate:.2f}%") print(f"加购→购买转化率:{cart_buy_rate:.2f}%") # 4. 转化漏斗可视化 funnel_data = { '行为环节': ['浏览', '收藏', '加购', '购买'], '用户数': [len(view_users), len(collect_users), len(cart_users), len(buy_users)], '转化率(%)': [100, view_collect_rate, view_cart_rate, view_buy_rate] } funnel_df = pd.DataFrame(funnel_data) # 创建转化漏斗图 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6)) # 左图:用户数漏斗 sns.barplot(x='行为环节', y='用户数', data=funnel_df, ax=ax1, palette='Blues_r') ax1.set_title('电商用户行为转化漏斗(用户数)', fontsize=14, fontweight='bold') ax1.set_ylabel('用户数', fontsize=12) ax1.set_xlabel('行为环节', fontsize=12) # 在柱状图上添加数值标签 for i, v in enumerate(funnel_df['用户数']): ax1.text(i, v + 1000, f'{v:,}', ha='center', va='bottom', fontsize=10) # 右图:转化率漏斗 sns.barplot(x='行为环节', y='转化率(%)', data=funnel_df, ax=ax2, palette='Oranges_r') ax2.set_title('电商用户行为转化漏斗(转化率)', fontsize=14, fontweight='bold') ax2.set_ylabel('转化率(%)', fontsize=12) ax2.set_xlabel('行为环节', fontsize=12) # 在柱状图上添加数值标签 for i, v in enumerate(funnel_df['转化率(%)']): ax2.text(i, v + 0.5, f'{v:.2f}%', ha='center', va='bottom', fontsize=10) plt.tight_layout() plt.savefig('user_behavior_funnel.png', dpi=300, bbox_inches='tight') plt.show() 分析结果解读:浏览→购买转化率仅为2.67%,说明大部分用户仅浏览未购买,存在明显转化瓶颈;加购→购买转化率(17.33%)高于收藏→购买转化率(13.56%),说明用户加购行为的购买意愿更强;可针对未转化用户(浏览未加购、加购未购买)制定精准营销策略,提升转化效率。2. 时间维度用户行为分析从小时、日期、星期三个时间维度分析用户行为规律,识别用户活跃高峰时段,为营销活动时间安排、服务器资源调度提供依据。 # 1. 小时维度行为分析(用户活跃时段分析) hour_behavior = df.groupby(['hour', 'behavior_type'])['user_id'].nunique().reset_index() hour_pivot = hour_behavior.pivot(index='hour', columns='behavior_type', values='user_id').fillna(0) # 绘制小时维度用户活跃曲线 plt.figure(figsize=(12, 6)) for behavior in ['view', 'collect', 'cart', 'buy']: plt.plot(hour_pivot.index, hour_pivot[behavior], marker='o', linewidth=2, label=behavior) plt.title('用户行为小时分布曲线', fontsize=14, fontweight='bold') plt.xlabel('小时', fontsize=12) plt.ylabel('活跃用户数', fontsize=12) plt.xticks(range(0, 24)) plt.grid(True, alpha=0.3) plt.legend(['浏览', '收藏', '加购', '购买'], fontsize=10) plt.tight_layout() plt.savefig('hour_behavior_distribution.png', dpi=300, bbox_inches='tight') plt.show() # 2. 星期维度行为分析 weekday_mapping = {0: '周一', 1: '周二', 2: '周三', 3: '周四', 4: '周五', 5: '周六', 6: '周日'} df['weekday_name'] = df['weekday'].map(weekday_mapping) weekday_behavior = df.groupby(['weekday_name', 'behavior_type'])['user_id'].nunique().reset_index() # 按星期顺序排序 weekday_order = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] weekday_behavior['weekday_name'] = pd.Categorical(weekday_behavior['weekday_name'], categories=weekday_order, ordered=True) weekday_behavior = weekday_behavior.sort_values('weekday_name') # 绘制星期维度用户行为柱状图 plt.figure(figsize=(12, 6)) sns.barplot(x='weekday_name', y='user_id', hue='behavior_type', data=weekday_behavior, palette='Set2') plt.title('用户行为星期分布', fontsize=14, fontweight='bold') plt.xlabel('星期', fontsize=12) plt.ylabel('活跃用户数', fontsize=12) plt.legend(['浏览', '收藏', '加购', '购买'], fontsize=10) plt.tight_layout() plt.savefig('weekday_behavior_distribution.png', dpi=300, bbox_inches='tight') plt.show() # 3. 日期维度行为分析(月度趋势) date_behavior = df.groupby(['date', 'behavior_type'])['user_id'].nunique().reset_index() date_pivot = date_behavior.pivot(index='date', columns='behavior_type', values='user_id').fillna(0) # 绘制日期维度用户行为趋势图 plt.figure(figsize=(15, 6)) for behavior in ['view', 'collect', 'cart', 'buy']: plt.plot(date_pivot.index, date_pivot[behavior], linewidth=2, label=behavior) plt.title('用户行为月度趋势(2024年1月)', fontsize=14, fontweight='bold') plt.xlabel('日期', fontsize=12) plt.ylabel('活跃用户数', fontsize=12) plt.xticks(rotation=45) plt.grid(True, alpha=0.3) plt.legend(['浏览', '收藏', '加购', '购买'], fontsize=10) plt.tight_layout() plt.savefig('date_behavior_trend.png', dpi=300, bbox_inches='tight') plt.show() 时间维度分析结果:(1)小时维度:用户活跃高峰集中在10:00-12:00、19:00-22:00,这两个时段是用户浏览、购买的黄金时间,可在此时段推送营销活动、优化客服响应;(2)星期维度:周末(周六、周日)用户活跃数明显高于工作日,尤其是购买行为,周末购买用户数比工作日平均高30%,可重点在周末开展促销活动;(3)日期维度:1月中旬(10-20日)用户活跃度较高,月末活跃度有所下降,可能与月底消费预算不足有关,可在月末推出低客单价商品促销。3. 商品类别分析分析不同商品类别的用户行为数据,识别热门类别、高转化类别,为商品布局、库存管理提供依据。 # 1. 各商品类别行为统计(按购买用户数排序) category_behavior = df.groupby(['category_id', 'behavior_type'])['user_id'].nunique().reset_index() category_pivot = category_behavior.pivot(index='category_id', columns='behavior_type', values='user_id').fillna(0) category_pivot['total_view'] = category_pivot['view'] category_pivot['buy_rate'] = (category_pivot['buy'] / category_pivot['view'] * 100).round(2) # 购买转化率 category_pivot = category_pivot.sort_values('buy', ascending=False).head(10) # 取购买用户数前10的类别 print("购买用户数前10的商品类别:") print(category_pivot[['view', 'collect', 'cart', 'buy', 'buy_rate']]) # 2. 热门商品类别可视化(购买用户数前10) plt.figure(figsize=(14, 8)) category_names = [f'类别{int(cid)}' for cid in category_pivot.index] # 子图1:各类别浏览vs购买用户数 ax1 = plt.subplot(2, 1, 1) x = np.arange(len(category_names)) width = 0.35 ax1.bar(x - width/2, category_pivot['view'], width, label='浏览用户数', color='skyblue') ax1.bar(x + width/2, category_pivot['buy'], width, label='购买用户数', color='orange') ax1.set_title('热门商品类别浏览与购买用户数', fontsize=12, fontweight='bold') ax1.set_ylabel('用户数', fontsize=10) ax1.set_xticks(x) ax1.set_xticklabels(category_names, fontsize=8) ax1.legend() ax1.grid(True, alpha=0.3, axis='y') # 子图2:各类别购买转化率 ax2 = plt.subplot(2, 1, 2) ax2.bar(category_names, category_pivot['buy_rate'], color='green', alpha=0.7) ax2.set_title('热门商品类别购买转化率', fontsize=12, fontweight='bold') ax2.set_ylabel('购买转化率(%)', fontsize=10) ax2.set_xlabel('商品类别', fontsize=10) ax2.grid(True, alpha=0.3, axis='y') # 添加转化率标签 for i, v in enumerate(category_pivot['buy_rate']): ax2.text(i, v + 0.2, f'{v:.2f}%', ha='center', va='bottom', fontsize=8) plt.tight_layout() plt.savefig('hot_category_analysis.png', dpi=300, bbox_inches='tight') plt.show() # 3. 商品类别行为偏好分析(收藏率、加购率) category_pivot['collect_rate'] = (category_pivot['collect'] / category_pivot['view'] * 100).round(2) category_pivot['cart_rate'] = (category_pivot['cart'] / category_pivot['view'] * 100).round(2) # 绘制收藏率vs加购率散点图 plt.figure(figsize=(10, 6)) plt.scatter(category_pivot['collect_rate'], category_pivot['cart_rate'], s=category_pivot['buy']*10, alpha=0.6, c='red') plt.title('商品类别收藏率与加购率关系(气泡大小=购买用户数)', fontsize=14, fontweight='bold') plt.xlabel('收藏率(%)', fontsize=12) plt.ylabel('加购率(%)', fontsize=12) plt.grid(True, alpha=0.3) # 为每个点添加类别标签 for i, cid in enumerate(category_pivot.index): plt.annotate(f'类别{int(cid)}', (category_pivot['collect_rate'].iloc[i], category_pivot['cart_rate'].iloc[i]), xytext=(5, 5), textcoords='offset points', fontsize=8) plt.tight_layout() plt.savefig('category_preference_analysis.png', dpi=300, bbox_inches='tight') plt.show() 商品类别分析结果:(1)热门类别:类别1001、类别2003、类别3005的购买用户数位居前三,是平台核心商品类别,应重点保障库存、优化商品展示;(2)高转化类别:类别2003的购买转化率达5.23%,远高于平均水平(2.67%),说明该类别商品用户需求旺盛、性价比高,可加大推广力度;(3)偏好分析:类别3005的收藏率和加购率均较高,用户购买意愿强烈,可针对该类别推出组合套餐、限时折扣等活动,进一步提升转化。4. 用户价值分析(RFM模型)RFM模型是用户价值分析的经典模型,通过Recency(最近一次购买时间)、Frequency(购买频率)、Monetary(购买金额)三个维度对用户进行分层,识别高价值用户、潜在价值用户等,为精准营销提供依据。由于本次数据集无购买金额字段,采用RF模型(Recency+Frequency)进行分析。 # 1. 筛选购买行为数据 buy_df = df[df['behavior_type'] == 'buy'].copy() # 计算分析截止日期(数据集最后一天+1) end_date = df['date'].max() + pd.Timedelta(days=1) # 2. 计算RF指标 rf_data = buy_df.groupby('user_id').agg({ 'date': lambda x: (end_date - x.max()).days, # Recency:最近一次购买距离截止日期的天数(越小越好) 'behavior_type': 'count' # Frequency:购买次数(越大越好) }).reset_index() rf_data.columns = ['user_id', 'recency', 'frequency'] print("RF指标统计:") print(rf_data.describe()) # 3. 对RF指标进行分箱(分为4个等级,1级最优,4级最差) rf_data['r_score'] = pd.qcut(rf_data['recency'], 4, labels=[4, 3, 2, 1]) # 最近购买时间越近,分数越高 rf_data['f_score'] = pd.qcut(rf_data['frequency'], 4, labels=[1, 2, 3, 4]) # 购买频率越高,分数越高 # 4. 计算用户价值总分(r_score + f_score) rf_data['user_value_score'] = rf_data['r_score'].astype(int) + rf_data['f_score'].astype(int) # 5. 用户分层(根据总分) def user_segment(score): if score >= 7: return '高价值用户' elif score >= 5: return '中高价值用户' elif score >= 3: return '中低价值用户' else: return '低价值用户' rf_data['user_segment'] = rf_data['user_value_score'].apply(user_segment) # 6. 用户分层统计 user_segment_count = rf_data['user_segment'].value_counts().reset_index() user_segment_count.columns = ['user_segment', 'user_count'] user_segment_count['user_ratio'] = (user_segment_count['user_count'] / user_segment_count['user_count'].sum() * 100).round(2) print("\n用户分层统计:") print(user_segment_count) # 7. 用户价值分层可视化 plt.figure(figsize=(10, 6)) colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'] sns.barplot(x='user_segment', y='user_count', data=user_segment_count, palette=colors) plt.title('用户价值分层分布', fontsize=14, fontweight='bold') plt.xlabel('用户分层', fontsize=12) plt.ylabel('用户数', fontsize=12) # 添加用户数和占比标签 for i, (count, ratio) in enumerate(zip(user_segment_count['user_count'], user_segment_count['user_ratio'])): plt.text(i, count + 20, f'{count:,}\n({ratio:.2f}%)', ha='center', va='bottom', fontsize=10) plt.tight_layout() plt.savefig('user_value_segmentation.png', dpi=300, bbox_inches='tight') plt.show() # 8. 各分层用户行为特征分析(结合浏览、收藏、加购行为) segment_behavior = df.merge(rf_data[['user_id', 'user_segment']], on='user_id', how='left') segment_behavior_stats = segment_behavior.groupby(['user_segment', 'behavior_type'])['user_id'].nunique().reset_index() segment_behavior_pivot = segment_behavior_stats.pivot(index='user_segment', columns='behavior_type', values='user_id').fillna(0) segment_behavior_pivot['total_behavior'] = segment_behavior_pivot.sum(axis=1) segment_behavior_pivot['buy_ratio'] = (segment_behavior_pivot['buy'] / segment_behavior_pivot['total_behavior'] * 100).round(2) print("\n各分层用户行为特征:") print(segment_behavior_pivot[['view', 'collect', 'cart', 'buy', 'buy_ratio']]) 用户价值分析结果:(1)用户分层分布:高价值用户占比仅5.23%,中高价值用户占比18.76%,中低价值用户占比45.12%,低价值用户占比30.89%,符合“二八定律”,少数用户贡献核心价值;(2)高价值用户特征:最近购买时间近、购买频率高,同时浏览、收藏、加购行为活跃,购买转化率达35.67%,是平台重点维护对象,可提供专属权益、会员服务等,提升用户粘性;(3)低价值用户特征:最近购买时间远、购买频率低,浏览行为多但转化少,可通过个性化推荐、新人优惠券等