
前言pandas 是 Python 里最常用的第三方数据分析库它把带标签的表格数据 抽象成两个对象Series一维和DataFrame二维。几乎所有 pandas 操作 都是在这两个对象上做选择、变换和聚合。这篇是基础篇重点放在数据结构、索引和运算对齐这三块根子上。 很多人跳过这些直接学 API结果在两个 Series 相加为什么冒出 NaN 这类问题上卡很久——原因就藏在索引对齐alignment里。先交代前提pandas 是第三方库需要pip install pandas 本文的运行环境里没有 Python 解释器也没有 pandas示例无法运行验证 只能逐行人工推演。参数细节一律以 Pandas 官方文档为准。一、Series带标签的一维数组# pandas 1.0import pandas as pds pd.Series([3, 1, 2], index[c, a, b], namescore)print(s.values) # [3 1 2]底层是 NumPy 数组print(s.index) # Index([c, a, b], dtypeobject)print(s.name) # score要点不传index时默认用从 0 开始的整数索引s.values是底层的 NumPy 数组较新版本也可用s.to_numpy()name是给这列起的名字在放进DataFrame时会被用作列名索引可以重复也可以不是整数Series并不要求索引唯一。二、DataFrame二维表DataFrame是共享同一行索引的多列。创建方式主要有三种# pandas 1.0# 方式一用字典键是列名、值是列数据df1 pd.DataFrame({name: [A, B], age: [25, 30]})# 方式二用列表的列表配 columns 指定列名df2 pd.DataFrame([[A, 25], [B, 30]], columns[name, age])# 方式三从 NumPy 数组构造import numpy as nparr np.array([[1, 2], [3, 4]])df3 pd.DataFrame(arr, columns[x, y])三种方式得到的都是二维表。df1的行索引是默认的RangeIndex(0, 2) 列索引就是[name, age]。属性返回什么df.index行索引df.columns列索引df.values/df.to_numpy()底层二维数组df.dtypes每列类型df.shape(行数, 列数)df.size元素总个数三、索引pandas 的灵魂pandas 的运算默认按索引对齐这是它和 NumPy 数组最大的区别# pandas 1.0a pd.Series([1, 2, 3], index[x, y, z])b pd.Series([10, 20], index[y, z])print(a b)# x NaN# y 12# z 23a b没有按位置加而是按索引标签匹配x在b里没有对应结果就是NaN。 理解了这一点缺失值的大量出现、concat后数据错位就都能解释了。行索引有两个常用操作# pandas 1.0df df.set_index(name) # 把某列设为行索引df df.reset_index() # 把行索引还原成普通列reset_index()在分组、透视之后特别常用因为那时分组键往往变成了索引。索引还有一类特殊的形态叫多层索引MultiIndex 它把多个键叠在一起当索引比如城市 月份。它功能强但容易记混层级 入门阶段可以先只掌握单层索引遇到多层时用reset_index()摊平成普通列再处理 能回避掉大量层级定位的麻烦。四、选择数据的三种入口# pandas 1.0df[age] # 选一列 - Seriesdf[[name, age]] # 选多列 - DataFramedf.loc[A, age] # 按标签df.iloc[0, 1] # 按位置df[df[age] 26] # 布尔过滤一句话记忆方括号给字符串是选列、给布尔序列是筛行loc认标签iloc认位置。两者的另一个差异在切片loc的切片a:c两端都含iloc的切片0:2含头不含尾和 Python 列表一致。要取单个格子时还有一对更快的标量访问器df.at[行标签, 列名]和df.iat[行位置, 列位置]。它们专门用于取一个值返回的是标量而不是Series 语义上就是loc/iloc的单点版。五、常见的数据操作# pandas 1.0df df.rename(columns{age: 年龄}) # 改列名df df.sort_values(年龄, ascendingFalse) # 排序df[年龄] df[年龄].astype(int64) # 类型转换df[标签] df[年龄].map(lambda x: 高 if x 28 else 低) # 逐元素映射df df.drop(columns[标签]) # 删列astype用于转换列类型map用于对Series做逐元素映射rename/sort_values/drop默认都返回新对象要接住返回值。 注意sort_values返回排好序的新表而列表的list.sort()是原地排序并返回None—— 两者行为不同不要照搬。在缺失值上基础阶段记住两个方法即可# pandas 1.0df.isna() # 哪些位置是缺失df.fillna(0) # 缺失填 0判定缺失要用isna()因为浮点的NaN连自己都不等于自己。读取和写出是另一个基础块常用函数命名很规律read_csv/read_excel读文件to_csv/to_excel写文件。读 CSV 时留意encoding中文常见utf-8与gbk读 Excel 时留意参数名是sheet_name。写出时若不想把 行号写进文件记得indexFalse。六、一个完整的小练习# pandas 1.0import pandas as pddef demo() - pd.DataFrame:df pd.DataFrame({name: [A, B, C], age: [25, 30, 28]})df df.set_index(name)df[adult] df[age] 18 # 布尔列df[age_next] df[age] 1return df.reset_index()if __name__ __main__:print(demo())常见坑点以为两个 Series 相加是按位置❌ 两份索引不同的Series直接相加以为逐位对加 ✅ 记住是按索引标签对齐对不上就是NaN必要时先reset_indexdf[a]与df[[a]]不分❌df[a]当表格用后面df[a][新列] ...报错 ✅ 单列是Series要保留二维结构就用双括号loc与iloc的切片端点混淆❌ 以为.loc[a:c]不含c或者.iloc[0:2]含位置 2 ✅loc两端都含iloc含头不含尾sort_values当成原地排序❌df.sort_values(age)之后直接用df发现顺序没变 ✅ 接住返回值df df.sort_values(age)drop忘了指定columns❌df.drop(标签)想删列实际被当成删行报 KeyError ✅df.drop(columns[标签])或df.drop(标签, axis1)astype转换失败不处理❌ 把含空值的字符串列astype(int64)直接抛错 ✅ 用astype(Int64)可空整数或先清理缺失再转链式赋值改不到原对象❌df[df[age] 26][标签] 高在旧版报警告、新版可能无效 ✅df.loc[df[age] 26, 标签] 高以为索引只能是整数❌ 用df[0]去取第 0 行若索引是字符串会 KeyError ✅ 按位置取用iloc按标签取用loc两者别混总结主题关键点Series一维、带索引、有nameDataFrame二维、共享行索引、列有类型运算按索引对齐对不上出NaN选择方括号选列/筛行loc标签、iloc位置切片loc两端含iloc含头不含尾变换rename/sort_values/drop返回新对象缺失isna()判定、fillna()填充pandas 基础的核心不是背方法名而是建立索引是骨架、运算按标签对齐的心智模型。 把这两点吃透后面学merge、groupby、透视表时都会轻松很多。