Pandas 增删改查超全实战(附可运行源码)

数据分析避不开 Pandas,而 DataFrame 的增、删、改、查更是每天都在用的基本功。这篇文章用一份 1960--2019 全球 GDP 数据 从头走一遍四大操作,每一个都带可运行代码 + 运行结果 + 踩坑提示,建议收藏后跟着敲一遍。

0. 准备数据

复制代码
import pandas as pd

# 注意:原文件是 GBK 编码,必须指定 encoding='gbk'
df = pd.read_csv('data/1960-2019全球GDP数据.csv', encoding='gbk')

print(df.columns)  # Index(['year', 'country', 'GDP'])
df.head()

数据一共三列:year(年份)、country(国家)、GDP(数值)。后面所有操作都基于它,演示时经常用 df[:5].copy() 拷贝前 5 行出来做试验,避免污染原始数据。

小习惯:练习增删改一定要先 .copy(),否则很容易在不知不觉中改掉原表。


一、增:新增列

给 DataFrame 加列有两大思路:直接赋值assign()

思路 1:直接赋值 df['新列'] = ...

复制代码
df2 = df[:5].copy()

# 写法1:固定值(整列都是同一个数)
df2['c1'] = 23

# 写法2:传入列表(长度必须和行数一致)
df2['c2'] = ['cxk', 'lyf', 'wyf', 'wyb', '水冷哥']

# 写法3:用已有列做运算,生成新列
df2['c3'] = df2['year'] * 2

# 写法4:通过函数返回值生成新列
def my_func1():
    return 25000

df2['c4'] = my_func1()

df2

运行结果 :新增了 c1/c2/c3/c4 四列,行数不变。

⚠️ 踩坑:写法 2 的列表长度必须和 DataFrame 行数完全相等 ,否则直接报 ValueError。写法 3 是最高频的用法,本质是 "拿一列(Series)做运算得到新列"。

思路 2:assign () 链式新增

复制代码
df3 = df[:5].copy()

# 新增1列
df3 = df3.assign(c1=23)

# 新增多列(一次性搞定)
df3 = df3.assign(
    c1=23,
    c2=['cxk', 'lyf', 'wyf', 'wyb', '水冷哥'],
    c3=df3['year'] * 2,
    cf=my_func1()
)
df3

assign() 的优势是可以链式调用、一次加多列 ,且它本身不会修改原表,必须用返回值接住

对比:df['c1']=23 直接改原表;assign() 返回新表。两者都常用,喜欢链式编程选 assign


二、删:删除行 / 列 / 去重

2.1 删行

复制代码
df4 = df[:10].copy()

df4 = df4.drop(0)            # 删 index=0 那一行
df4 = df4.drop([0, 2, 4])    # 删多个指定 index
df4 = df4.drop(index=0)      # 用 index 参数,更明确
df4 = df4.drop(index=[0, 2, 4])
df4

drop 默认按 行标签(index) 删,返回新表,不改原表。

2.2 删列

复制代码
# 方式A:axis=1(0是行,1是列)
df4 = df4.drop('GDP', axis=1)

# 方式B:columns 参数(推荐,一眼看懂)
df4 = df4.drop(columns=['country'])
df4

⚠️ 踩坑:删列必须指定轴 ,用 columns=[...] 最清晰;写 drop('GDP') 会默认按行找,找不到就报 KeyError

2.3 去重

去重用 drop_duplicates()

复制代码
df_dup = df[['country']].copy()

# 按 country 去重,保留第一条
uniq = df_dup.drop_duplicates()

# 只按 country 去重,并保留最后一次出现的记录
uniq_last = df_dup.drop_duplicates(subset='country', keep='last')

# 查看去重后的国家数量
print(len(uniq))

三、改:替换数据

改的核心工具就是 replace(),它有两种作用域:全局 DataFrame 替换、单列 Series 替换。

3.1 单列直接改

复制代码
df5 = df[:5].copy()

df5['c1'] = 23                              # 整列覆盖为固定值
df5['GDP'] = [1, 23, 666666, -48, 6]        # 整列覆盖为列表

# 单值替换:把 '美国' 换成 'usa'
df5['country'] = df5['country'].replace('美国', 'usa')

# 字典多值替换
df5['country'] = df5['country'].replace({
    '英国': 'GB',
    '法国': 'FR'
})
df5

3.2 全局 DataFrame 替换(多列多值)

复制代码
# 写法1:inplace 修改原表
df5.replace({'country': {'日本': '岛国'}}, inplace=True)

# 写法2:一次性替换多个国家(推荐)
df6 = df[:5].copy()
df6 = df6.replace({
    'country': {
        '美国': 'usa',
        '日本': '岛国',
        '中国': 'cn',
        '英国': 'GB',
        '法国': 'FR'
    }
})
df6

两种写法怎么选:

表格

写法 作用域 适用场景
df['col'].replace({旧:新}) 单列 Series 只改一列,逻辑简单,优先推荐
df.replace({'列': {旧:新}}) 整个 DataFrame 多列不同替换规则

⚠️ 重点踩坑:不要在单列上写 inplace=True

复制代码
df['country'].replace('美国', 'usa', inplace=True)  # ❌ 警告!

df['country'] 返回的是中间副本,对它 inplace 根本改不到原表。Pandas 3.0 之后这种写法会直接失效 。 ✅ 正确姿势:赋值回去 df['country'] = df['country'].replace('美国', 'usa')


四、查:取数据 + 条件筛选

4.1 head / tail

复制代码
df.head()   # 默认前5条
df.tail(3)  # 后3条

4.2 按列名取

复制代码
df['year']    # 返回 Series(一维)
df.year       # 点语法,同上(列名简单、不重名时可用)
df[['year']]  # 返回 DataFrame(二维)

⚠️ 踩坑:df['year']df[['year']] 差一个括号,返回类型完全不同 ------ 前者一维 Series,后者二维 DataFrame。点语法 df.year 遇到列名含空格 / 中文、或和 size/count 等内置方法重名时会出错,正式代码建议用 df['year']

4.3 按行取(切片 /loc/iloc)

复制代码
print(df[:5])        # 前5行(位置切片)
print(df[1:5:2])     # 位置1、3 两行(步长2)
print(df[10::5])     # 从位置10到末尾,步长5

print(df.loc[0:2, :])   # 按【行标签】取 0~2 行(含端点)
print(df.iloc[0:2, :])  # 按【数字位置】取 0、1 两行(不含端点)

⚠️ 核心易错点:

  • df[]传字符串 / 字符串列表 = 取列 ;传切片 a:b = 取行
  • df[] 的切片按行位置,不是行标签。
  • df.loc[0:2] 按标签取且含端点df.iloc[0:2] 按位置取且不含端点。2.x 下行标签恰好是 0、1、2... 时容易混,改了 index 后立马露馅。

4.4 query () 条件筛选(重点)

复制代码
# 需求:中国、美国、日本 三国 2015~2019 年的数据
result = df.query(
    "country in ['中国','美国','日本'] and (year >= 2015 and year <= 2019)"
)
result

query 多条件用法速查:

表格

需求 写法
并且(and) "age > 18 and score > 80"
并且(&) "age > 18 & score > 80"
或者 "age == 18 or score > 88"
in 多值匹配 "country in ['中国','美国']"
引用外部变量 "year >= @min_year"
列名含空格 "user age > 20"(反引号包裹)

提示:query 里字符串常量要加引号'中国'),数字不用;外部变量必须加 @。query 返回新表,不会改原表,记得用变量接住。


五、全文速记(收藏版)

操作 一句话写法
增列 df['c']=...df=df.assign(c=...)
删行 df=df.drop(index=[0,2])
删列 df=df.drop(columns=['col'])
去重 df=df.drop_duplicates(subset='col')
改单列 df['c']=df['c'].replace({旧:新})
改多列 df=df.replace({'列':{旧:新}})
取前 N 行 df.head(N)
按列名取 df['col'] / df[['col']]
按位置取 df.iloc[行, 列]
按标签取 df.loc[行, 列]
条件筛选 df.query("条件 and/or 条件")

六、完整可运行源码

把下面这段存成 pandas_crud.py 直接跑,全部结论都能复现(记得把 CSV 路径换成你自己的):

复制代码
import pandas as pd

# 0. 读数据
df = pd.read_csv('data/1960-2019全球GDP数据.csv', encoding='gbk')

# 1. 增
df2 = df[:5].copy()
df2['c1'] = 23
df2['c2'] = ['a', 'b', 'c', 'd', 'e']
df2['c3'] = df2['year'] * 2
df2 = df2.assign(c4=25000, c5=df2['year'] * 10)

# 2. 删
df4 = df[:10].copy()
df4 = df4.drop(index=[0, 2, 4])
df4 = df4.drop(columns=['GDP'])
uniq = df[['country']].drop_duplicates()

# 3. 改
df6 = df[:5].copy()
df6['country'] = df6['country'].replace({'中国': 'CN', '英国': 'GB'})

# 4. 查
result = df.query("country in ['中国','美国','日本'] and (year >= 2015 and year <= 2019)")
print(result)

如果对你有帮助,欢迎一键三连(点赞 + 收藏 + 关注)。 下期可以继续聊聊 groupby 聚合、merge 合并,或者把这份数据做成可视化。评论区告诉我你想看哪个方向,我来安排!

相关推荐
benchmark_cc2 天前
REST API 和 Python SDK 应该怎么选?量化交易数据接口选型实战
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
三十岁老牛再出发3 天前
8月27日总结
python·pandas
砚底藏山河3 天前
【量化纯GET实战 #21】用 pandas 做分析:把接口数据变成 DataFrame
java·python·金融·maven·pandas
Patrick在香港4 天前
把 Claude 塞进 pandas 管道:7 条脏地址实测,5 条自动清洗、2 条被闸门拦下
python·pandas·etl·claude·数据清洗
智购科技无人售货机工厂4 天前
2026自动售货机云端API设计规范:从RESTful到GraphQL的接口演进~YH
android·人工智能·驱动开发·单片机·云原生·pandas·设计规范
quantdash_cc5 天前
批量请求和循环请求有什么区别?从 API 请求次数看量化数据获取的工程设计
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
三十岁老牛再出发11 天前
8月25-26日总结
python·pandas
观察员13 天前
用 Pandas 对抓取的电影数据进行分析
pandas
人工干智能13 天前
科普:pandas 时间偏移别名:ts.resample(“5Min“).sum()
python·pandas