Python 数据处理入门(二)Series 与 DataFrame:把一张表格装进内存
先确认示例数据在手边import os import mkdata # 第 1 篇里的 mkdata.py ​ if not os.path.exists(data/sales.csv): mkdata.main() # 没生成过就先跑一次 print(示例数据就绪, os.path.exists(data/sales.csv))这段会检查第 1 篇生成的data/目录在不在不在就自动补一次已经有数据时只会打印一行示例数据就绪 True不影响后面的结果。写在前面本系列已更新到第 2 篇。上一篇我们把 Pandas 装上、跑通了第一个程序还生成了后面 11 篇要用的data/示例数据。这一篇解决一个更底层的问题Pandas 里的表格到底是什么东西。搞不清这一点后面每一次报错你都只能靠猜搞清了取数、改数、算数基本就是顺手的事。一、Series一列数据 一排标签一句话Series 就是带标签的一列数据。左边是标签索引右边是值每个值都能被自己的标签叫出来。import pandas as pd ​ # 数据 索引标签顺手起个名字 s pd.Series([120, 95, 60, 88], index[杭州, 上海, 北京, 广州], name销量) print(s) print(----) print(索引, s.index.tolist()) print(数值, s.values) print(按标签取一个, s[上海]) print(按标签取多个, s[[杭州, 广州]].tolist()) print(合计, s.sum())杭州 120 上海 95 北京 60 广州 88 Name: 销量, dtype: int64 ---- 索引 [杭州, 上海, 北京, 广州] 数值 [120 95 60 88] 按标签取一个 95 按标签取多个 [120, 88] 合计 363打印结果左侧是标签、右侧是值底部的Name: 销量是它的名字dtype: int64是数值类型。注意最后两行的取值写法取一个用一层方括号取多个要再套一层方括号。这个多一层方括号表示多选的规则DataFrame 完全一样先记牢它。二、用字典造一张 DataFrameDataFrame 可以理解成共用同一套行索引的好几列 Series 拼起来的一张表。最快的造表方式是给一个字典键是列名值是这一列的内容。import pandas as pd ​ df pd.DataFrame( { 城市: [杭州, 上海, 北京, 广州], 销量: [120, 95, 60, 88], 单价: [49.9, 29.9, 89.0, 599.0], } ) print(df.to_string(indexFalse)) print(----) # 另一种常见写法列表套列表再手动指定列名 df2 pd.DataFrame([[杭州, 120, 49.9], [上海, 95, 29.9]], columns[城市, 销量, 单价]) print(df2.to_string(indexFalse)) print(----) print(index 行标签, df.index.tolist()) print(columns 列名, df.columns.tolist()) print(shape行数, 列数, df.shape) print(values 纯数据只取数值列) print(df[[销量, 单价]].values)城市 销量 单价 杭州 120 49.9 上海 95 29.9 北京 60 89.0 广州 88 599.0 ---- 城市 销量 单价 杭州 120 49.9 上海 95 29.9 ---- index 行标签 [0, 1, 2, 3] columns 列名 [城市, 销量, 单价] shape行数, 列数 (4, 3) values 纯数据只取数值列 [[120. 49.9] [ 95. 29.9] [ 60. 89. ] [ 88. 599. ]]三个地方值得停一下字典里每列的列表长度必须一样少写一个值就会报ValueError: All arrays must be of the same length这是新手最高频的造表报错index/columns/values是看骨架的三件套前两个是行标签和列名values是去掉标签后的纯数据numpy 数组。整张表混了文本时values会退化成 object 数组所以一般只对数值列用它to_string(indexFalse)是为了打印时不显示左边那列 0、1、2 的行号看起来更像 Excel。三、取一列、取多列取列只有两种写法区别就在方括号的层数上。import pandas as pd ​ df pd.DataFrame( { 城市: [杭州, 上海, 北京, 广州], 销量: [120, 95, 60, 88], 单价: [49.9, 29.9, 89.0, 599.0], } ) # 一层方括号取一列得到 Series col df[城市] print(df[城市] 是, type(col).__name__, , col.tolist()) # 两层方括号取多列得到 DataFrame two df[[城市, 销量]] print(df[[城市, 销量]] 是, type(two).__name__, ) print(two.to_string(indexFalse))df[城市] 是 Series [杭州, 上海, 北京, 广州] df[[城市, 销量]] 是 DataFrame 城市 销量 杭州 120 上海 95 北京 60 广州 88df[城市]是 Seriesdf[[城市]]是只有一列的 DataFrame。什么时候必须区分当你要接着调head()、to_excel()这类表才有的方法时就得是 DataFrame只是看数值、求和、比较Series 更省事。四、加一列、删一列列与列直接算给一个不存在的列名赋值就是新增一列更舒服的是列与列之间能直接做四则运算不用写 for 循环。import pandas as pd ​ df pd.DataFrame( { 城市: [杭州, 上海, 北京, 广州], 销量: [120, 95, 60, 88], 单价: [49.9, 29.9, 89.0, 599.0], } ) # 新增一列两列直接相乘整列一起算 df[金额] (df[销量] * df[单价]).round(2) print(df.to_string(indexFalse)) print(----) # 删除列drop 默认返回新表不动原表 df.drop(columns[单价]) print(只写 drop 不赋值列还在, df.columns.tolist()) df_new df.drop(columns[单价]) print(赋值给新变量之后, df_new.columns.tolist()) print(----) # 删除行用 index 参数 print(df.drop(index[0, 2]).to_string(indexFalse))城市 销量 单价 金额 杭州 120 49.9 5988.0 上海 95 29.9 2840.5 北京 60 89.0 5340.0 广州 88 599.0 52712.0 ---- 只写 drop 不赋值列还在 [城市, 销量, 单价, 金额] 赋值给新变量之后 [城市, 销量, 金额] ---- 城市 销量 单价 金额 上海 95 29.9 2840.5 广州 88 599.0 52712.0这段有两个新手必踩的点一是df[金额] ...是直接改原表而drop是返回新表不赋值等于白删二是整列相乘靠的是向量化运算几十万行也是一瞬间千万不要用 for 循环一行行去算。五、loc 与 iloc按名字取还是按位置取规则一句话loc 认标签iloc 认位置。两者的写法都是[行, 列]只写行就是取整行。import pandas as pd ​ df pd.DataFrame( { 城市: [杭州, 上海, 北京, 广州], 销量: [120, 95, 60, 88], 单价: [49.9, 29.9, 89.0, 599.0], } ) df[金额] (df[销量] * df[单价]).round(2) ​ print(默认索引是 0、1、2、3 时loc[1] 和 iloc[1] 看起来一样) print(df.loc[1].to_string()) print(单个格子, df.loc[1, 金额]) print(----) print(切片就分道扬镳了loc[0:2] 是, df.loc[0:2].shape[0], 行含右端点iloc[0:2] 是, df.iloc[0:2].shape[0], 行不含) print(----) city_df df.set_index(城市) print(把城市设成索引后loc 可以直接用城市名取) print(city_df.loc[[杭州, 广州], [销量, 金额]].to_string()) print(iloc 依然按位置取第 2 行) print(city_df.iloc[1].to_string()) print(----) df3 df.copy() df3.index [10, 20, 30, 40] print(索引改成 [10, 20, 30, 40] 后loc[10] 取到, df3.loc[10, 城市]) print(索引里还有标签 0 吗, 0 in df3.index.tolist())默认索引是 0、1、2、3 时loc[1] 和 iloc[1] 看起来一样 城市 上海 销量 95 单价 29.9 金额 2840.5 单个格子 2840.5 ---- 切片就分道扬镳了loc[0:2] 是 3 行含右端点iloc[0:2] 是 2 行不含 ---- 把城市设成索引后loc 可以直接用城市名取 销量 金额 城市 杭州 120 5988.0 广州 88 52712.0 iloc 依然按位置取第 2 行 销量 95.0 单价 29.9 金额 2840.5 ---- 索引改成 [10, 20, 30, 40] 后loc[10] 取到 杭州 索引里还有标签 0 吗 False最后两行是重点索引变成 10 开头之后df3.loc[0]会直接报KeyError: 0因为它找的是标签 0而表里根本没有这个标签这时只有iloc[0]能拿到第一行。只要索引不是默认的 0、1、2、3用 loc 就必须写真实标签——从 Excel 读进来带了自定义索引的表最容易在这里翻车。六、索引对齐NaN 是怎么冒出来的Pandas 最容易让人懵的行为来了两个 Series 相加时它先按标签配对再相加对不上的标签直接给 NaN。它不看顺序只看标签。import pandas as pd ​ s1 pd.Series([1, 2, 3], index[杭州, 上海, 北京]) s2 pd.Series([10, 20], index[上海, 广州]) print(s1 s2) print(----) # 给表加一列时也是按标签对齐顺序打乱也能对上 df pd.DataFrame({销量: [120, 95, 60]}, index[杭州, 上海, 北京]) price pd.Series([89.0, 49.9, 29.9], index[北京, 杭州, 上海]) df[单价] price print(df.to_string()) print(----) # 索引里多了个表里没有的成都对不上就是 NaN df[单价2] pd.Series([49.9, 29.9], index[杭州, 成都]) print(df.to_string())上海 12.0 北京 NaN 广州 NaN 杭州 NaN dtype: float64 ---- 销量 单价 杭州 120 49.9 上海 95 29.9 北京 60 89.0 ---- 销量 单价 单价2 杭州 120 49.9 49.9 上海 95 29.9 NaN 北京 60 89.0 NaNs1 s2只有上海两边都有所以只有它算出 12.0其余三行全是 NaN。第二段里price的顺序被故意打乱但对齐之后 49.9 依然准确落在杭州——对齐认标签不认顺序。第三段最贴近实战从别处拿来的 Series 索引和主表对不上加进去就是一片 NaN。所以后面第 4 篇做数据探查时要专门数一遍缺失值第 6 篇还要分清本来就缺和对不齐造出来的缺。七、拿 sales.csv 对照一遍内存里的小表看懂了换成真表来一遍。这次我们读第 1 篇生成的销售明细用列运算把它原有的金额列验算一遍。import pandas as pd ​ sales pd.read_csv(data/sales.csv, encodingutf-8-sig) print(列名, sales.columns.tolist()) print(sales[[产品, 数量, 单价, 金额]].head(5).to_string(indexFalse)) print(----) # 列与列相乘自己重算一遍金额 sales[重算金额] (sales[数量] * sales[单价]).round(2) bad sales[sales[金额] ! sales[重算金额]] print(和原金额对不上的行) print(bad[[订单日期, 产品, 金额, 重算金额]].to_string(indexFalse))列名 [订单日期, 城市, 产品, 数量, 单价, 销售员, 金额] 产品 数量 单价 金额 A-笔记本 3 49.9 149.7 B-鼠标 5 29.9 149.5 B-鼠标 5 29.9 149.5 C-键盘 2 89.0 178.0 A-笔记本 4 49.9 199.6 ---- 和原金额对不上的行 订单日期 产品 金额 重算金额 2024-02-11 B-鼠标 NaN 179.4 2024-04-18 D-显示器 NaN 1198.0 2024-05-20 D-显示器 -599.0 2995.0真表里正好三种情况都齐了两行原金额是空的NaN一行金额是负数录入错了而它们用「数量 × 单价」重算出来的数字都没问题。这也说明 DataFrame 的列运算不只是算数还能顺手当数据质量检查用。常见问题Q1df[0]为什么取不到第一行方括号里写整数时Pandas 会把它当列名去查报KeyError: 0。想按位置取第一行用df.iloc[0]想取某一列用df[列名]。记住方括号里是列名不是行号。Q2df.drop(columns[单价])执行了为什么表没变drop、head、sort_values这些方法默认返回新对象不改原表。想留下结果就赋值df df.drop(columns[单价])。养成返回新表 → 赋值给变量的习惯比记一堆原地修改的参数省心得多。Q3为什么我的dtypes显示str文章里是objectobject是 Pandas 里Python 字符串对象的经典写法早期版本统一这么显示pandas 3.x 起文本列默认换成了新的str类型于是在新版本上跑就会看到str。两者是同一个意思在.str字符串方法、比较运算、read_csv上的用法完全一样看到哪个都不用慌。真要判断这列是不是文本稳妥的写法是select_dtypes(excludenumber)第 4 篇会用到。小结这一篇把 Pandas 的两个核心对象摸了一遍Series 是带标签的一列DataFrame 是共用一套行索引的多列取列靠方括号的层数加列靠赋值删列删行靠droploc 认标签、iloc 认位置而所有跨对象的运算都会先按标签对齐对不上就填 NaN。这几个规则看着简单但它们是后面筛选、清洗、分组、合并的地基——你之后遇到的绝大多数莫名其妙的结果都能从这几条里找到解释。下一篇我们聊怎么把 CSV 和 Excel 文件正确地读进来编码、路径、表头、只读部分列、多 sheet、大文件分块一次讲清。

相关新闻

责任链模式在参数校验中的优雅实践

责任链模式在参数校验中的优雅实践

1. 项目概述最近在重构一个老项目的用户注册模块时,我被满屏的if-else判断折磨得够呛。一个简单的手机号注册功能,竟然嵌套了12层条件判断!每次新增一个校验规则,都要在已经臃肿不堪的代码堆里再塞进一个分支。这让我开始思考&…

2026/10/15 7:11:53 阅读更多 →
计算机网络基础:OSI与TCP/IP模型及核心协议解析

计算机网络基础:OSI与TCP/IP模型及核心协议解析

1. 计算机网络基础概念回顾计算机网络第二课通常会从OSI七层模型和TCP/IP四层模型开始讲起。这两种模型是理解网络通信的基础框架,也是后续学习各种网络协议的前提。OSI模型将网络通信划分为七个层次:物理层:负责比特流的传输数据链路层&…

2026/10/15 7:10:53 阅读更多 →
POM四大反模式:你的页面对象是巨无霸还是空壳?

POM四大反模式:你的页面对象是巨无霸还是空壳?

上个月帮一个自动化测试项目做代码走查,打开那个放在项目里号称"核心复用层"的Page文件时,我差点以为走错了目录——一个类里面堆了四十多个公开方法,从登录框定位到购物车结算,再到个人中心头像修改,应有尽…

2026/10/15 7:10:53 阅读更多 →

最新新闻

低延迟趋势线LLT:从EMA到二阶滤波的交易择时Python实现

低延迟趋势线LLT:从EMA到二阶滤波的交易择时Python实现

简介:广发证券发布的《低延迟趋势线与交易择时》金融工程专题报告,面向技术分析者、量化策略研究员与短线交易者,针对传统移动平均线(MA)平滑性与延迟性难以兼顾的痛点,系统介绍低延迟趋势线(LL…

2026/10/15 7:52:01 阅读更多 →
224G PAM4收发器如何用3pJ/bit功耗突破40dB信道损耗

224G PAM4收发器如何用3pJ/bit功耗突破40dB信道损耗

简介:IEEE《固态电路期刊》2025年1月刊论文PDF,主题为3nm FinFET CMOS工艺的224 Gb/s PAM-4长距离收发器,面向高速串行接口、SerDes、集成电路与信号处理方向的研究人员与工程师。内容覆盖数据中心800G/1.6T交换机、AI加速器等高带宽需求&…

2026/10/15 7:52:01 阅读更多 →
HTTP与HTTPS核心差异及Python实现详解

HTTP与HTTPS核心差异及Python实现详解

1. HTTP与HTTPS基础概念解析HTTP(HyperText Transfer Protocol)和HTTPS(HyperText Transfer Protocol Secure)是每个Python开发者必须掌握的基础网络协议。我在实际面试候选人时发现,90%的初级开发者能说出"HTTPS…

2026/10/15 7:52:01 阅读更多 →
CentOS 7下vsftpd中文乱码根因与兼容性解决方案

CentOS 7下vsftpd中文乱码根因与兼容性解决方案

1. 项目概述:为什么vsftpd在CentOS 7里会“说错话”?你有没有遇到过这样的场景:用FileZilla连上一台CentOS 7服务器的vsftpd服务,上传一个叫“测试文档.txt”的文件,结果在服务器上ls一看,变成了一串问号或…

2026/10/15 7:52:01 阅读更多 →
JNI线程管理与同步机制深度解析

JNI线程管理与同步机制深度解析

1. JNI线程操作基础解析在JVM与本地代码交互的场景中,线程管理是JNI编程最关键的难点之一。不同于纯Java环境,JNI线程涉及Java线程与本地线程(如pthread)的双向交互,需要特别注意线程附着(Attach&#xff0…

2026/10/15 7:52:01 阅读更多 →
Caveman调试法:极简打印输出快速定位代码问题

Caveman调试法:极简打印输出快速定位代码问题

先交代一下背景:我最近在梳理自己这几年写的工具脚本和自动化流程时,发现有一类问题我一直在用最“笨”的办法解决,但效果反而最稳定。我想了想,这套思路挺像很多人说的“caveman debugging”,也就是极简调试法——不用…

2026/10/15 7:51:01 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →