📊 第4章 Pandas 进阶
📄 一句话概括

to_dict 不给 orient 就是按列,要一行一个字典必须写 orient='records'。 values 给 numpy 数组,要纯 Python 列表得再 .tolist(),两个连用最多。 遍历行优先用 itertuples,比 iterrows 快很多,也保住了字段名。

📝 本章和前面几章的关系

前面十篇都在「把数据弄进来、算明白」。这一篇讲「把结果交出去」。 交给接口用字典,交给脚本用列表,交给老板用网页表格。

一、转字典:to_dict

df.to_dict() 默认按列:{'姓名': [...], '语文': [...]}。 按记录转:df.to_dict(orient='records') 给「一行一个字典」的列表。 第一个元素长这样:{'姓名': '张伟', '语文': 88}。

orient 不给就是按列。要喂给接口就写 records,这是最通用的形状。 还有 orient='list'(值转成列表)、orient='index'(行标签当键)几种。

二、转列表:values

df[ ['语文','数学'] ].values.tolist() 给二维列表:[ [88, 92], [92, 95]]。 单列直接 df['语文'].tolist():[88, 92, 75, 85]。 values 给的是 numpy 数组,不是列表。要纯 Python 对象必须再 tolist。

为什么在乎这个?因为很多库只吃 list,喂 ndarray 会报类型错或者行为诡异。 两个连用是最常见的写法:先 values 去掉标签,再 tolist 变成列表。

三、转元组:itertuples

for row in df.itertuples(index=False) 每行给一个命名元组。 打出来是 Pandas(姓名='张伟', 语文=88),字段能按名字取。 它比 iterrows 快很多:iterrows 每行都造一个 Series,还要做类型转换。

遍历行优先用 itertuples。iterrows 会把整行的类型统一,整数可能变成小数。 要字典形状就用 _asdict(),命名元组自带这个方法。

四、转网页:to_html

df.to_html(index=False) 返回一段 table 标签的字符串,这次 334 个字符。 写进文件 375 字节,双击就能在浏览器里打开一张表。 to_html 只给表格本身,没有任何样式。要好看的网页得自己套 CSS。

它的用处是「快速给人看一眼」,不是「做一个网站」。 要和别人共享,导出 xlsx 通常比 html 更实用——对方能改、能再算。

五、动手 Demo:DataFrame 与字典、列表、元组、网页互转

一张三行两列的小表,依次转成字典、列表、元组、HTML。 每转一次都打一下类型,看清楚拿到的是什么。

import pandas as pd

D = pd.DataFrame({"姓名": ["张伟", "王芳", "李娜"],
                  "语文": [88, 92, 75]})

print("按列 %s" % list(D.to_dict().keys()))
print("按记录 %s" % D.to_dict(orient="records")[0])
print("转列表 %s" % D[ ["姓名", "语文"]].values.tolist()[0])

for row in D.itertuples(index=False):
    print(row, "->", row._asdict())

HTML = D.to_html(index=False)
print("html 长度 %d" % len(HTML))
print(HTML.splitlines()[0])

实跑输出:

--------------------------------------------------------------------
DataFrame 与字典、列表、元组、网页互转
--------------------------------------------------------------------

  ① 转字典:to_dict
  --------------------------------------------------------------------
  默认方向是按列:['姓名', '语文']。
  按记录转:{'姓名': '张伟', '语文': 88}。
  按列转成列表:{'姓名': ['张伟', '王芳', '李娜'], '语文': [88, 92, 75]}。
  ! orient 不给就是按列。要一行一个字典就写 records,这是给接口最常用的形状。

  ② 转列表:values
  --------------------------------------------------------------------
  二维数组:[ [88, 92], [92, 95]]。
  单列转列表:[88, 92, 75, 85]。
  values 给的是 numpy 数组,要纯 Python 列表得再 .tolist()。
  ! values 是「不要标签的裸数据」,tolist 是「变成 Python 对象」。两个连用最多。

  ③ 转元组:itertuples
  --------------------------------------------------------------------
  每一行是一个命名元组:Pandas(姓名='张伟', 语文=88)。
  它比 iterrows 快很多,也比 values 多了字段名。
  ! 遍历行优先用 itertuples。iterrows 会把整行变成 Series,慢且会把类型改掉。

  ④ 转网页:to_html
  --------------------------------------------------------------------
  to_html 返回一段 table 标签的字符串,长度 334 字符。
  前 60 个字符:<table border="1" class="dataframe">
  <thead>
    <tr style
  写进文件 375 字节,双击就能在浏览器里看。
  ! to_html 只给表格本身,没有样式。要好看的网页得自己套 CSS。

itertuples 打出来的第一列是 Pandas(姓名='张伟', 语文=88)——类型名就叫 Pandas。 _asdict() 把命名元组转成字典。要给接口塞一行数据,这一步很顺手。

30 秒实验

  1. 把 to_dict 的 orient 换成 'index',看键变成什么。
  2. 把 itertuples 的 index=False 去掉,看每行多出来什么。
  3. 想一想:为什么 iterrows 比 itertuples 慢?多做了哪些事?

常见误区

  1. 以为 to_dict 默认一行一个字典:默认是按列,形状完全不同。
  2. values 直接当 list 用:它是 ndarray,有些地方行为不一样。
  3. 遍历大表用 iterrows:慢几十倍,整数还会被转成小数。
  4. 把 to_html 当网页模板:只有裸表格,没有样式和布局。
自测三问(点开对答案) 1. to_dict 默认是什么形状? —— 按列:键是列名,值是一整列的列表。要一行一个字典得写 orient='records'。 2. values 和 tolist 各做什么? —— values 把表变成 numpy 数组(去掉标签),tolist 再把数组变成纯 Python 列表。 3. itertuples 比 iterrows 好在哪? —— 快得多,而且不会把整行的类型统一掉;还保留了字段名,能按名字取值。

单表处理完了。下一篇把两张表接起来:merge 与 concat。

相关笔记