☰
香港知识产权公开统计实测:同一个「外观设计申请数」,两份表差了 3.74 倍
2026/9/28 20:19:49 网站建设 项目流程

目录

    • 一、三份表,三种形态
    • 二、跨表对账:2,168 对 8,111
    • 三、表内也有三个量纲:申请数 ≠ 设计数 ≠ 类别合计
    • 四、列名和行标签里塞了别的东西
    • 五、时点存量和年度流量不能放在一张图上
    • 六、可以直接抄的做法
    • 参考链接

这两天有个很热的话题:AI 把一项物理学的世界纪录刷新了,接着就是「AI 做出来的东西算谁的」这种讨论。这个问题我答不了,但我顺手打开了中国香港知识产权署的公开统计——三份零鉴权的 CSV,只想做一件事:把 2025 年的外观设计申请数找出来。结果第一脚就踩空了:

  • 一份表(按来源地和类别划分)里,2025 年的申请数是2,168;
  • 另一份表(按国家或地区划分)里,同一年同一个指标的合计是8,111——差 3.74 倍;
  • 而第一份表里还藏着第三个数:这些申请共含 4,038 个设计,也就是说一份申请平均装了 1.86 个设计。

三份文件加起来不到 20KB,但形态、口径、时间语义全都不一样。

一、三份表,三种形态

文件行数列数形态时间语义
按来源地和类别20436长表(年份是一个字段)年度流量(只有 2025)
按国家或地区526宽表(年份当列名)年度流量(2021–2025)
有效注册/批予数56宽表(列名是「截至某日」)时点存量

同一个发布者、同一个网站目录,三份文件的组织方式没有一个是相同的:一份年份躺在字段里、一份年份躺在列名里、一份列名干脆就是日期。你要是想写一个「通用读取器」套这三份表,光是「年份在哪」这个问题就有三种答案。

顺便看一眼第二份表那五年的合计:7,755 → 6,605 → 7,153 → 9,201 → 8,111。它自己就在上下摆动,所以「某年涨了多少」这种说法,离开具体年份的绝对值是没有意义的。

二、跨表对账:2,168 对 8,111

先看最刺眼的那个差:

# 两份都在讲「外观设计申请数」的表,对一下 2025 年importcsv,io,pathlib RAW=pathlib.Path("原始返回/ipd")defrows(name,rnd=0):text=(RAW/f"{name}_r{rnd}.csv").read_bytes().decode("utf-8-sig")return[rforrincsv.reader(io.StringIO(text))ifrandany(x.strip()forxinr)]defnum(v):v=(vor"").strip()returnint(v)ifv.isdigit()else0A=rows("origin_class")# 长表:国家 × 年份 × 32 个类别B=rows("country")# 宽表:国家 × 五年a_apps=sum(num(r[2])forrinA[1:]ifr[1]=="2025")a_designs=sum(num(r[3])forrinA[1:]ifr[1]=="2025")b_total=sum(num(r[i])forrinB[1:]fori,yinenumerate(B[0][1:],start=1)ify=="2025")print(a_apps,a_designs,b_total,round(b_total/a_apps,2))# 2168 4038 8111 3.74

2,168、4,038、8,111——三个数都在描述同一年的同一件事,最大值是最小值的 3.74 倍,绝对值差 5,943。

我没有找到任何一处说明解释这个差,所以我不打算猜哪个是对的。这里真正有价值的是那个动作本身:跨表对账。很多时候你手上的「权威数字」是从某个表随手取的,而同一个发布者的另一份表里躺着另一个数;只有把两份摆在一起,你才会发现「这个指标不是唯一的」。引用之前至少要确认三件事:统计对象(申请 / 设计 / 类别)、覆盖范围(204 个地区 vs 52 个地区)、时间语义(年度还是截至某日)。

三、表内也有三个量纲:申请数 ≠ 设计数 ≠ 类别合计

再往第一份表里面看,它自己就提供了三个总量:

rows25=[rforrinA[1:]ifr[1]=="2025"]apps=sum(num(r[2])forrinrows25)# 申请数designs=sum(num(r[3])forrinrows25)# 申请所含设计数classes=sum(sum(num(x)forxinr[4:36])forrinrows25)# 32 个类别分项之和print(apps,designs,classes,round(designs/apps,2),classes==designs)# 2168 4038 4038 1.86 Truezero=sum(1forrinrows25ifnotany(num(x)forxinr[2:]))print("整行全 0 的国家/地区:",zero,"/",len(rows25))# 整行全 0 的国家/地区: 170 / 204

三个结论:

  1. 洛迦诺类别分项之和(4,038)正好等于「设计数」(4,038),差 0——这是一条能自证的恒等式,说明这份表里「一个设计对应一个类别」。拿到新数据时先找这种等式跑一遍,比读文档快;
  2. 设计数是申请数的 1.86 倍——一份外观申请可以装多个设计。把「设计数」当「申请数」报出去,会凭空多出 86%;
  3. 204 个国家/地区里 170 个整行是 0(83.3%),只有 34 行有数。所以按「国家」做排序或算平均时,分母到底是 204 还是 34,会给出完全不同的结论。

四、列名和行标签里塞了别的东西

第三份表(有效注册/批予数)只有 5 行,但它的标签很野:

C=rows("inforce")labels=[r[0]forrinC[1:]]print(len(C[0][0]),max(len(x)forxinlabels))print([x[:38]forxinlabelsif"Note"inx])print([repr(x)forxinlabelsifx!=x.strip()])print(C[0][1:])# 29 116# ['Standard Patents (O) (Note: The Patents Registry started...']# ["'Standard Patents (R) '"]# ['as at 31.12.2022', 'as at 31.12.2023', 'as at 31.12.2024',# 'as at 31.12.2025', 'as at 31.8.2026']

三件事:

  • 行标签里嵌了整段脚注:Standard Patents (O) (Note: The Patents Registry started to receive standard patent (O) applications on 19.12.2019.)——116 个字符,其中只有前 21 个是真正的名称。拿它当字典键、当数据库字段、当图表图例,都会变成一场灾难;
  • 行标签带尾部空格:'Standard Patents (R) ',strip 之前和"Standard Patents (R)"是两个不同的键;
  • 列名就是数据:as at 31.12.2022一直到as at 31.8.2026,五个时点。这不是五个「年份」,是五个快照日期;最后一个是 8 月底,不是年末——所以它跟前面四个年末的存量数字不完全可比。

顺带说第一份表:它的第一列列名有182 个字符(整段关于 WIPO 2025 问卷的说明都塞在列名里)。这不算错,但影响很实际——任何按「列名是否等于预期值」做的校验都会失败,任何把列名直接当数据库字段名或图例的做法都会炸。正确姿势是给列做一层显式映射:位置 → 内部名,不要让列名参与业务逻辑。

五、时点存量和年度流量不能放在一张图上

第三份表给的是存量(截至某日有效的注册数),前两份给的是流量(某年的申请数)。这两类数字最常见的误用是放在一起做「趋势图」:把 2021–2025 的申请数和截至各年的有效量画在同一条轴上,看起来像同一条曲线,实际一个是「今年新增多少」,一个是「账上还剩多少」。

看一眼就能发现区别:有效外观设计从 40,448 涨到 41,830,五年涨 3.4%;而年度申请量在 6,605 到 9,201 之间来回摆。存量平滑、流量波动——把它们混在一起,你既看不出波动,也会低估存量。

六、可以直接抄的做法

defload_ipd(path:str):"""读知识产权署统计:宽表转长表 + 标签清洗 + 口径登记。"""out=[]withopen(path,encoding="utf-8-sig")asf:rows=[rforrincsv.reader(f)ifrandany(x.strip()forxinr)]head=rows[0]forrinrows[1:]:label=r[0]# 行标签:去掉脚注括号、去掉尾部空格label=re.split(r"\(Note",label)[0].strip()forcol,valinzip(head[1:],r[1:]):v=num(val)ifvisNone:continueout.append({"label":label,"period":col.strip(),"value":v,"kind":"存量"ifcol.strip().startswith("as at")else"流量"})returnout

四个要点收尾:跨表对账要在取数当天就做,同一个指标有多份表时,把它们的数字摆在一起再决定用哪个;表内先找恒等式再算比率(本文的「类别合计 = 设计数」差 0 就是一条);标签先清洗再当键(去脚注、去尾部空格);分清存量与流量,别把两类数字画在同一条轴上。

今天 6 次请求(三份表各两轮)全部真实抓取,原始文件已落盘,脚本可以整篇复跑。

参考链接

  1. https://www.ipd.gov.hk/datagovhk/ipstatistics/en/Statistics-of-design-applications-by-origin-class.csv
  2. https://www.ipd.gov.hk/datagovhk/ipstatistics/en/No_of_registrations_grants_in_force_in_hong_kong.csv
  3. https://data.gov.hk/en-data/api/3/action/package_show?id=hk-ipd-ipstat-statistics-design-applications-by-origin-class

原创声明:本文所有数据于 2026 年 9 月 27 日实测抓取自中国香港知识产权署公开统计文件与 data.gov.hk,抓取与校验脚本随文附上,欢迎复现。

文中 2,168 / 4,038 / 8,111 三个数字分别来自两份不同的官方统计文件,其口径差异未见官方说明;本文只呈现差异与核对方法,不推断哪一个为准,引用前请自行向发布方确认统计对象与覆盖范围。

如果这篇帮你避开了一次「数字取错表」的事故,点个收藏,下一篇继续拆官方统计的坑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询