尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Python + pandas 实现六个月创业公司滚动纪录分析

Python + pandas 实现六个月创业公司滚动纪录分析 Germany Sets New Six-Month Startup Record 是一则典型创业生态新闻标题。它对外呈现的是结论但真正值得技术开发的读者关注的是结论背后的数据链路这条记录从哪里统计出来、口径是什么、如何按月份聚合、六个月滚动窗口怎么计算、中间哪些数据清洗步骤会导致结果偏差。这篇文章会围绕这个标题搭建一个最小可运行的 Python 分析项目用 CSV、SQLite 和 pandas 把“创业公司月度记录”这个抽象概念转成可复现的脚本。项目不依赖商业数据库也不需要复杂分布式环境本地能跑通之后也能按生产要求逐步扩展。文章的内容会覆盖数据口径、环境准备、编码实现、运行验证、常见排错和工程化建议。最终产出一个能计算六个月滚动总数并判断是否创纪录的命令行脚本同时输出 Markdown 格式的分析报告。1. 先理解“六个月创业公司记录”背后的数据口径1.1 这条记录到底在统计什么新闻标题里的 six-month startup record通常不是指某一天新注册了多少家公司而是指在过去连续六个月的时间窗口内新成立、新融资或新登记创业公司的数量创下了历史同期新高。这类统计的难点不在“新高”两个字而在“六个月内”“创业公司”“新成立”这三个口径会因数据源不同而完全不一样。如果按工商注册信息统计需要从每个州的企业注册库中筛选出符合公司类型、成立时间、注册地址等条件的记录。如果按融资公告统计则要看新闻源是否覆盖了足够多的早期融资轮次。如果按孵化器或数据库定义还需要排除子公司、分支机构、变更名称后的壳公司等干扰项。也就是说同一个标题背后至少存在三种统计口径。本项目的目标不是证明新闻标题真实与否而是提供一个可替换口径的分析框架。使用者可以自行决定“创业公司”指什么、数据源从哪里来、日期字段取注册日还是公告日。框架一旦确定记录是否刷新就会变成纯粹的数据计算问题。1.2 为什么自己动手做这件事有价值直接用新闻标题的结论无法处理下面几个问题数据源是否完整有没有遗漏某个地区或月份的记录。日期格式是否统一跨月份数据有没有出现归属误差。是否存在同一家公司在不同时间点被重复计入统计。六个月窗口是滚动计算还是固定自然年上半年。这些问题只有通过自己搭建数据管道才能在每一步看到中间结果。市面上确实有商业数据库可以直接给出统计数字但这些数字往往封装在平台内部无法被审计。对于以数据为生的开发团队自建一条最小链路反而更容易定位偏差。1.3 本文项目的技术目标整个项目围绕一条明确主线展开从原始输入文件出发得到“是否创下新纪录”的结论。具体目标可以拆成四步。读入包含创业公司事件记录的结构化数据。清洗日期、公司名称、地区、来源等字段。按月份聚合计算每个月的创业公司数量。使用六个月滚动窗口计算连续半年的累计值并判断最新值是否超过历史纪录。输出包括控制台日志、统计结果表格和一份 Markdown 报告。这套流程既能用于分析德国创业数据也可以替换国家、地区或事件类型后用于其他市场。2. 环境准备与数据模型设计2.1 本地 Python 环境与依赖安装本项目选择 Python 作为实现语言因为数据处理生态成熟pandas 对日期聚合和滚动窗口的支持比较直接。建议使用 Python 3.10 或 3.11并用虚拟环境隔离依赖。mkdir startup-record-analysis cd startup-record-analysis python -m venv venv source venv/bin/activateWindows 下激活命令改为venv\Scripts\activate激活后安装依赖pip install pandas matplotlib jinja2将依赖写入 requirements.txt方便后续重建环境pip freeze requirements.txt注意pandas 2.x 中部分时间别名已经调整例如月份别名从M改为ME。因此建议在项目早期就把 pandas 版本锁定避免换环境后 API 变化导致脚本报错。2.2 示例数据源 CSV 结构为了让项目不依赖外部网络接口先使用本地 CSV 作为输入。CSV 是数据管道中最通用的交换格式方便用 Excel、数据库导出或脚本生成。下面定义一个最小字段集合字段名类型说明event_datedate创建公司或公告成立信息的日期company_namestring公司名称industrystring所属行业statestring所在州或地区sourcestring数据来源描述urlstring原始链接或唯一标识字段不贪多够用即可。真实数据源往往会有几百个字段但判断“某个月份有多少家创业公司”只需要事件日期和公司标识其他字段用于过滤和数据校验。示例 CSV 文件命名为sample_startups.csvevent_date,company_name,industry,state,source,url 2024-01-05,Berlin Analytics,AI,BE,startbase,https://example.com/1 2024-01-18,Munich Quantum,Hard Tech,BY,startbase,https://example.com/2 2024-02-02,Hamburg Logistics,Tech,HH,startbase,https://example.com/3 2024-02-20,Leipzig Bio,Health,SN,startbase,https://example.com/4 2024-03-09,Frankfurt Fintech,Fintech,HE,startbase,https://example.com/5 2024-03-27,Cologne Greentech,Climate,NW,startbase,https://example.com/6 2024-04-08,Dresden Materials,Hard Tech,SN,startbase,https://example.com/7 2024-04-21,Stuttgart Mobility,Auto,BW,startbase,https://example.com/8 2024-05-14,Nuremberg Energy,Climate,BY,startbase,https://example.com/9 2024-05-28,Potsdam AI,AI,BB,startbase,https://example.com/10 2024-06-03,Bremen Robotics,Hard Tech,HB,startbase,https://example.com/11 2024-06-25,Dusseldorf Bio,Health,NW,startbase,https://example.com/12这里的数据是演示使用不代表真实德国创业记录。读者可以按相同结构替换成自己采集到的真实数据。2.3 SQLite 表设计与迁移思路CSV 适合对账和人工检查但不适合多次运行。幂等性是数据管道的重要要求重复执行脚本不应产生重复数据。因此项目引入 SQLite 作为落地存储用数据库唯一约束保证数据不会重复入库。建表脚本如下CREATE TABLE IF NOT EXISTS startups ( id INTEGER PRIMARY KEY AUTOINCREMENT, event_date TEXT NOT NULL, company_name TEXT NOT NULL, industry TEXT, state TEXT, source TEXT, url TEXT, created_at TEXT DEFAULT CURRENT_TIMESTAMP, UNIQUE(company_name, event_date, source) );三个字段组成的唯一约束可以拦截“同一家公司、同一天、来自同一来源”的重复记录。不同来源的相同公司不会被拦截因为新闻源之间可能重复报道同一事件这种重复会在后续行业分析中单独处理。如果以后需要切换 PostgreSQL 或 MySQLSQL 结构变化不大。唯一约束仍然有效只是日期类型需要从TEXT改为DATE或TIMESTAMP。3. 核心代码实现从 CSV 到六个月滚动统计3.1 数据读取流程项目入口采用脚本加参数方式便于在命令行直接运行。先创建analyze_startup_records.py然后定义三个核心函数读取 CSV、写入 SQLite、执行统计。import argparse import sqlite3 from pathlib import Path import pandas as pd def read_csv_to_dataframe(csv_path: str) - pd.DataFrame: df pd.read_csv(csv_path) print(f[INFO] 读取到 {len(df)} 条原始记录) return df这里使用 pandas 的read_csv它会对表头、分隔符、空值做初步处理。生产环境还可以指定dtype参数避免长文本被错误推断为数值类型。3.2 数据清洗要处理的三类问题原始数据直接进入统计会造成很多隐藏问题。第一个问题是日期格式不统一。有的数据源输出2024-01-05有的输出2024/1/5还有的包含时间戳2024-01-05 10:30:00。统一转换用pd.to_datetime。第二个问题是公司名称前后空格和大小写不一致。同一个公司如果写成了Berlin Analytics和berlin analytics聚合时会被当成两家公司。第三个问题是来源重复。从 A 网站和 B 网站都可能发布同一条融资信息需要在清洗阶段按指定字段去重。下面是清洗函数def clean_dataframe(df: pd.DataFrame) - pd.DataFrame: df df.copy() # 删除完全没有日期的记录 df df[df[event_date].notna()] # 统一日期格式errorscoerce 会把无法解析的日期转成 NaT df[event_date] pd.to_datetime(df[event_date], errorscoerce) df df[df[event_date].notna()] # 清理文本字段 for col in [company_name, industry, state, source]: if col in df.columns: df[col] df[col].astype(str).str.strip() # 去掉公司名称为空的记录 df df[df[company_name].notna()] df df[df[company_name].str.len() 0] # 按来源去重保留一条即可 df df.drop_duplicates(subset[company_name, event_date, source]) print(f[INFO] 清洗后保留 {len(df)} 条有效记录) return df清洗后的 DataFrame 还需要写入 SQLite保证后续重复运行时不会在数据库中堆积脏数据。写入函数def write_to_sqlite(df: pd.DataFrame, db_path: str) - None: conn sqlite3.connect(db_path) try: df_sqlite df.copy() df_sqlite[event_date] df_sqlite[event_date].dt.strftime(%Y-%m-%d) df_sqlite.to_sql( startups, conn, if_existsappend, indexFalse, methodmulti, ) print(f[INFO] 数据已写入 {db_path}) finally: conn.commit() conn.close()这里的关键点是先把 datetime 转换成字符串再写入 SQLite。SQLite 本身没有日期类型只存TEXT读取时再转换避免不同驱动对日期时区的解释不一致。3.3 按月份聚合的标准做法聚合目标是得到每个月的创业公司数量。使用pd.Period或resample都可行但推荐先将日期列作为索引再用resample(ME)聚合这样空月份会自动补零避免后续滚动窗口因为缺少月份而计算错误。def aggregate_by_month(df: pd.DataFrame) - pd.DataFrame: df df.copy() df df.set_index(event_date) # ME 表示 month end生成连续自然月 monthly df.resample(ME).size().reset_index(namecount) monthly.columns [month, count] monthly[month] monthly[month].dt.to_period(M) print([INFO] 月度聚合完成) print(monthly.to_string(indexFalse)) return monthly使用resample(ME)后即使某个月没有任何记录也会在结果中出现一行count0。这一点非常关键。如果不补零pandas 的 rolling 函数会按行数滚动而不是按自然月滚动结果就会失真。3.4 计算六个月滚动总和并判断是否创纪录六个月滚动总和是指从当前月份向前推五个月的累计总和也就是连续六个自然月的总数。def compute_six_month_rolling(monthly: pd.DataFrame, window: int 6) - pd.DataFrame: df monthly.copy() df[rolling_count] df[count].rolling(windowwindow, min_periodswindow).sum() return dfmin_periodswindow表示不足六个月时不计算滚动值。这是为了避免样本不足时把三个月总和误判为最高纪录。判断是否创纪录的逻辑需要分两步。第一步计算历史最大值第二步比较当前值是否大于历史最大值。这里“历史”可以定义为时间窗口之前的所有月份也可以定义为包含当前值在内历史所有月份。为了贴近新闻表述判断逻辑为当前窗口值是否大于此前所有非空窗口的最大值。def detect_new_record(rolling_df: pd.DataFrame) - pd.DataFrame: df rolling_df.copy() # 计算此前最大值shift(1) 排除当前窗口 df[previous_max] df[rolling_count].shift(1).expanding().max() df[is_new_record] df[rolling_count] df[previous_max] current_month df[month].iloc[-1] current_value df[rolling_count].iloc[-1] prev_max df[previous_max].iloc[-1] if pd.isna(current_value): print([WARN] 当前月份没有足够六个月历史数据无法判断是否创纪录) elif current_value prev_max: print(f[RESULT] {current_month} 刷新新纪录{current_value}) else: print(f[RESULT] {current_month} 未刷新纪录当前值{current_value}此前的最大值{prev_max}) return df这里使用expanding().max()是理解这个逻辑的关键。shift(1)去掉当前值expanding()对在此之前的所有滚动值求最大值得到的就是进入当前窗口之前的历史最高。3.5 生成 Markdown 分析报告记录判断完成后把结果输出到 Markdown 文件方便后续放进仓库或邮件附件。报告至少包含统计周期、数据量、月度表格、滚动值表格和结论五部分。def generate_report(monthly: pd.DataFrame, rolling_df: pd.DataFrame, output_path: Path) - None: lines [] lines.append(# 创业公司六个月滚动记录分析报告) lines.append() lines.append( 本报告由分析脚本自动生成数据来源见输入文件。) lines.append() lines.append(## 月度统计) lines.append() lines.append(| 月份 | 新增创业公司数量 | 六个月滚动值 | 是否新纪录 |) lines.append(| --- | --- | --- | --- |) merged rolling_df.merge(monthly, onmonth, suffixes(_rolling, _monthly)) for _, row in merged.iterrows(): flag 是 if row.get(is_new_record) else 否 lines.append(f| {row[month]} | {row[count]} | {row[rolling_count]:.0f} | {flag} |) lines.append() lines.append(## 结论) lines.append() last merged.iloc[-1] if pd.isna(last[rolling_count]): lines.append(当前数据不足六个月无法给出滚动记录结论。) elif last[is_new_record]: lines.append(f截至 {last[month]}六个月滚动总数 {last[rolling_count]:.0f} 创下新纪录。) else: lines.append(f截至 {last[month]}六个月滚动总数为 {last[rolling_count]:.0f}未超过此前最大值。) output_path.write_text(\n.join(lines), encodingutf-8) print(f[INFO] 分析报告已生成{output_path})最终通过main函数串联整个流程。def main(): parser argparse.ArgumentParser(description分析创业公司六个月滚动记录) parser.add_argument(--csv, defaultsample_startups.csv, help输入 CSV 路径) parser.add_argument(--db, defaultstartups.db, helpSQLite 数据库路径) parser.add_argument(--output, defaultreport.md, help输出 Markdown 报告路径) args parser.parse_args() df read_csv_to_dataframe(args.csv) clean_df clean_dataframe(df) write_to_sqlite(clean_df, args.db) monthly aggregate_by_month(clean_df) rolling_df compute_six_month_rolling(monthly) result_df detect_new_record(rolling_df) generate_report(monthly, result_df, Path(args.output)) if __name__ __main__: main()4. 运行验证用演示数据跑通整个流程4.1 准备演示数据在项目目录下创建sample_startups.csv放入略多于六个月的数据。为了验证“创纪录”逻辑可以构造两批数据前七个月每月数量较低最后一个月突然升高。这样脚本应该判断最后一个月刷新纪录。完整演示数据示例event_date,company_name,industry,state,source,url 2024-01-05,Berlin Analytics,AI,BE,startbase,https://example.com/1 2024-01-18,Munich Quantum,Hard Tech,BY,startbase,https://example.com/2 2024-02-02,Hamburg Logistics,Tech,HH,startbase,https://example.com/3 2024-02-20,Leipzig Bio,Health,SN,startbase,https://example.com/4 2024-03-09,Frankfurt Fintech,Fintech,HE,startbase,https://example.com/5 2024-03-27,Cologne Greentech,Climate,NW,startbase,https://example.com/6 2024-04-08,Dresden Materials,Hard Tech,SN,startbase,https://example.com/7 2024-04-21,Stuttgart Mobility,Auto,BW,startbase,https://example.com/8 2024-05-14,Nuremberg Energy,Climate,BY,startbase,https://example.com/9 2024-05-28,Potsdam AI,AI,BB,startbase,https://example.com/10 2024-06-03,Bremen Robotics,Hard Tech,HB,startbase,https://example.com/11 2024-06-25,Dusseldorf Bio,Health,NW,startbase,https://example.com/12这个样本只有 12 条记录六个月窗口内总数较小主要用来验证脚本流程是否正确不适合做大范围推断。4.2 执行脚本并查看输出在项目目录运行python analyze_startup_records.py --csv sample_startups.csv --db startups.db --output report.md预期控制台输出结果类似[INFO] 读取到 12 条原始记录 [INFO] 清洗后保留 12 条有效记录 [INFO] 数据已写入 startups.db [INFO] 月度聚合完成 month count 0 2024-01 2 1 2024-02 2 2 2024-03 2 3 2024-04 2 4 2024-05 2 5 2024-06 2 [WARN] 当前月份没有足够六个月历史数据无法判断是否创纪录 [INFO] 分析报告已生成report.md当只有 6 个月数据时rolling_count在第一个六个月窗口才产生第一个有效值。由于没有更早的历史滚动值previous_max是空值所以无法创纪录。这是符合逻辑的一份新闻要宣称“创下新纪录”必然需要和更早的数据比较。如果继续补充 2024 年 7 月后的数据比如 2024 年 7 月有 8 条记录那么 2024 年 7 月的六个月滚动总数会显著上升脚本就会输出刷新纪录的判断。4.3 验证结果的正确性拿到结果后要从三个角度检查脚本是否正确。第一逐月核对总数。将count栏和 CSV 原始数据按月份计数对比确认没有多计和漏计。第二核对滚动值的计算。对任一行六个月滚动值应等于当前月份与前五个月的count之和。例如 2024 年 6 月的滚动值等于 2024 年 1 月至 6 月计数之和2 2 2 2 2 2 12第三检查去重逻辑。如果 CSV 中出现同一公司同一天同来源的重复行清洗后应只保留一条。可以手动输入重复行再次运行观察输出记录数是否会减少。注意不要只验证脚本能启动。数据管道的关键检查点是边界条件即空月份、重复记录、日期格式错误、窗口不足时脚本是否仍然正常结束。5. 从本地方案扩展到生产化数据管道5.1 学习环境与生产环境的差异本地方案适合验证算法和排错但离生产至少还差四个方面。第一数据源。生产环境中 CSV 往往来自客户导出或内部数据仓库导出原始文件可能达到几十万行清洗函数需要考虑分批读取。pandas 的read_csv支持chunksize参数可以分块处理。第二调度。新闻标题通常按季度或半年产生如果要做每日监控就需要使用定时任务。最轻量的是系统自带 cron 或 Windows 计划任务更规范的是 Apache Airflow、Prefect 或 Dagster。第三可观测性。脚本运行成功并不代表数据正确。生产环境应该在关键节点输出结构化日志包括原始行数、清洗后行数、去重率、时间覆盖范围并把这些指标发送到监控系统。第四存储。SQLite 适合单机小规模数据。当数据量增长或需要多人使用同一数据时建议迁移到 PostgreSQL并把表结构和唯一约束迁移过去。5.2 接入真实公开数据源的扩展方式如果不想手工维护 CSV可以定期从公开渠道采集创业公司公告。常见思路是抓取新闻源的 RSS 或调用公开 API但不同网站的结构差异很大示例代码只能给出方向。以下是一个简单的 HTTP 请求框架用于演示如何从新闻接口获取包含“startup”关键词的标题。实际项目需要替换为合法、可用的数据接口。import requests def fetch_articles(keyword: str, days: int 30): url https://example-news-api.com/search params { keyword: keyword, days: days, sort: publishedAt, } headers { Accept: application/json, } try: resp requests.get(url, paramsparams, headersheaders, timeout15) resp.raise_for_status() return resp.json() except requests.RequestException as exc: print(f[ERROR] 请求失败: {exc}) return []采集回来后需要从标题和正文中提取公司名、日期、地区。简单的做法是使用正则表达式抽取日期和公司名但准确性有限。更可靠的做法是使用命名实体识别或直接使用结构化数据库的导出字段。5.3 增加日志、异常处理和幂等保障生产脚本必须有异常处理。数据库写入失败、CSV 文件缺失、日期解析异常都不能让脚本无声退出。推荐的做法是使用 Python 的logging模块替代printimport logging logging.basicConfig( levellogging.INFO, format%(asctime)s [%(levelname)s] %(message)s, ) logger logging.getLogger(__name__) logger.info(开始处理 CSV 文件)数据库写入的幂等需要在建表后用INSERT OR IGNORE或先执行去重查询再插入。当前脚本使用to_sql的追加模式如果重复运行唯一约束会阻断重复行但to_sql遇到冲突时不会直接忽略可能导致异常。更稳妥的做法是先按唯一约束查询已存在记录或者先清空临时表再写入。5.4 可视化看板的方向Markdown 报告适合归档但看板更适合趋势分析。最简单的方式是使用 matplotlib 生成月度数量和六个月滚动趋势图。import matplotlib.pyplot as plt def plot_trend(monthly: pd.DataFrame, rolling_df: pd.DataFrame, output_path: str) - None: plt.figure(figsize(10, 5)) plt.plot(monthly[month].astype(str), monthly[count], label月度数量) plt.plot( rolling_df[month].astype(str), rolling_df[rolling_count], label六个月滚动值, markero, ) plt.xlabel(月份) plt.ylabel(创业公司数量) plt.title(创业公司月度数量与六个月滚动趋势) plt.xticks(rotation45) plt.legend() plt.tight_layout() plt.savefig(output_path)生产环境考虑使用数据可视化工具接入 SQLite 或 PostgreSQL例如 Apache Superset 或 Grafana。它们能直接读取数据库表不需要写太多前端代码。6. 常见问题排查从现象倒推原因6.1 滚动值列出现大量 NaN现象输出表格中rolling_count只有最后几行有值前面全是NaN。最常见原因是min_periods6设置正确但数据只有不足 6 个月或者某些月份缺失导致滚动窗口无法对齐。另一个原因是在rolling()之前没有用resample(ME)补全空月份而是直接按原始行滚动导致前几个窗口内的行数不足 6。排查顺序查看月度聚合结果确认月份是否连续。检查count列是否存在为 0 的月份。确认resample(ME)生效。确认rolling(window6, min_periods6)参数没有写错。6.2 日期解析出现大量 NaT现象清洗后有效记录数变为 0日志显示所有日期的event_date都是无效值。常见原因是 CSV 中日期列名不一致或者使用了datetime格式但代码指定了错误的列名。排查时先输出原始数据的前几行确认列名是否为event_date。print(df.head()) print(df.dtypes)如果列名正确再检查pd.to_datetime的errors参数。推荐使用errorscoerce将无法解析的值变成NaT并过滤掉而不是抛出异常中断整个脚本。6.3 重复运行脚本导致统计数量翻倍现象第一次运行脚本统计结果为 12 条第二次运行同样的 CSV统计结果变成 24 条。原因是to_sql使用追加模式唯一约束没有生效或约束字段不够严格。排查时先查询数据库SELECT COUNT(*) FROM startups;然后查看唯一索引是否存在SELECT name, sql FROM sqlite_master WHERE typetable AND namestartups;解决方案是调整UNIQUE字段组合并在写入前删除旧数据。最可靠的做法是在脚本开头直接使用DROP TABLE IF EXISTS startups重建表适合全量更新场景增量更新场景则需要先按来源和日期查询已有记录。6.4 月份聚合顺序错误现象月度表格不是从 1 月到 12 月而是按字母顺序排列。这是因为month列被转换成字符串后Markdown 或 DataFrame 显示层按字典排序。排查时先看打印的原始类型确认是否需要把月份转成Period类型。monthly[month] monthly[month].dt.to_period(M)Period类型天然支持时间排序输出 Markdown 时再转换字符串即可保持正确顺序。7. 可复用清单创业公司记录分析项目的最佳实践以下清单可以直接粘贴到项目 README作为新环境运行和代码审查的参考。环境检查清单Python 版本大于等于 3.10。虚拟环境已激活。requirements.txt 已安装pandas 版本与报告一致。输入 CSV 文件存在且首行包含event_date,company_name,industry,state,source,url字段。输出目录可写。代码运行前检查清单检查日期字段是否有非空值。检查月份是否连续空月份是否需要补 0。检查company_name去重字段组合是否合理。检查数据库唯一约束是否匹配源数据特性。生产发布前检查清单配置文件外置CSV 路径、数据库路径、窗口大小不使用硬编码。关键步骤打印结构化日志包含输入行数、清洗后行数、去重率。重复运行脚本不会产生重复数据。输出报告包含生成时间和数据范围说明。有异常告警机制例如日志关键字监控。扩展方向建议将 CSV 输入替换为内部数据库查询日期字段直接使用TIMESTAMP。引入消息队列每日增量采集新闻数据后触发聚合任务。增加按行业、按州的下钻分析观察是哪个行业或地区带动了记录增长。在滚动窗口之外增加同比对比即当前六个月与去年同期六个月比较避免周期性影响。如果用户只关注互联网、AI 等领域可以在清洗层增加行业过滤规则减少无关数据干扰。整个项目最核心的判断逻辑并不复杂复杂的是统计口径、日期清洗和窗口计算。只要把这三点做好“是否创下新纪录”就会变成一个明确可回答的问题。对于想深入数据工程的开发者建议先把这个最小项目跑通再逐步把输入源、存储和调度替换成生产环境组件这样既不会一开始就陷入复杂架构也能在每一步看到数据变化。
返回列表