四、loc和iloc —— 精准定位的核心武器

特性 loc iloc
索引依据 标签(列名/行索引名) 整数位置(0, 1, 2...)
切片规则 闭区间(含首尾) 左闭右开
布尔条件 ✅ 支持 ❌ 不支持
# loc - 按标签选择(推荐!)
df.loc[0]                           # 第0行
df.loc[0:3]                         # 第0-3行(共4行)
df.loc[0:3, ['产品类别', '销售额']]  # 特定行和列
df.loc[df['销售额'] > 200, '产品类别', '订单ID', '地区', '销售员']  # 条件选择+列

# iloc - 按位置选择
df.iloc[0]                          # 第0行
df.iloc[0:3]                        # 第0-3行(不含3)(共3行)
df.iloc[0:3, 0:2]                   # 前3行,前2列

五、query() 方法

  • 基础条件

    df.query('销售额 > 1000')
    
  • 多条件

    df.query("地区 == '华北' and 销售额 > 1200")
    
  • 引用外部变量(用 @ 符号)

    threshold = 1000
    region = '华东'
    df.query("销售额 > @threshold or 地区 == @region")
    
  • 列表匹配

    df.query("产品类别 in ['电子', '食品']")
    
  • 字符串方法(需指定 engine='python')

    df.query("订单ID.str.contains('B')", engine='python')
    

六、筛选后赋值 —— 批量修改数据

  • 基于条件修改值

    df_demo = df.copy()
    
    # 华北区电子类销售额打9折(只改指定行列)
    df_demo.loc[
        (df_demo['地区'] == '华北') & (df_demo['产品类别'] == '电子'), 
        '销售额'
    ] *= 0.9
    
  • 新增计算列(模拟 Excel IF)

    df_demo['利润'] = df_demo['销售额'] - df_demo['成本']
    df_demo['高利润标记'] = df_demo['利润'] > 500
    
    # np.where 嵌套实现多分支判断(替代 Excel 的 IF 嵌套)
    df_demo['业绩评级'] = np.where(
        df_demo['销售额'] >= 1500, '优秀',
        np.where(df_demo['销售额'] >= 1000, '良好', '一般')
    )
    

七、综合实战:生成业务报表

  • 场景:提取「华北区高价值未退货订单明细」,并计算毛利率。
# 筛选 + 选择指定列
report = df.loc[
    (df['地区'] == '华北') & 
    (df['销售额'] >= 1200) & 
    (~df['是否退货']) & 
    (df['客户评分'] >= 4.0),
    ['订单ID', '日期', '产品类别', '销售额', '成本', '客户评分', '销售员']
].copy()

# 新增计算列
report['毛利率'] = ((report['销售额'] - report['成本']) / report['销售额'] * 100).round(2)

# 排序
report = report.sort_values('销售额', ascending=False)

print(report)

# 进一步分组汇总
summary = report.groupby('产品类别').agg({
    '销售额': 'sum',
    '毛利率': 'mean',
    '订单ID': 'count'
}).rename(columns={'订单ID': '订单数'})

附录:常见错误与性能建议

坑点

正确做法

df[0:2, ['列1']] 报错

基础 [] 不支持同时行列,用 df.loc[0:2, ['列1']]

(df.A > 1) and (df.B < 2) 报错

(df.A > 1) & (df.B < 2),且每个条件加括号

df.loc[0:2]  df.iloc[0:2] 结果不同

loc 是闭区间,iloc 是左闭右开

修改视图(SettingWithCopyWarning)

筛选后赋值先用 .copy(),如 df_sub = df[...].copy()

大数据量性能瓶颈

连续筛选建议合并为一个 loc 条件,减少中间对象

本周练习

练习1:用你的工作数据完成以下筛选

  1. 筛选出销售额大于10000的记录

    df[df['price']>10000]
    
  2. 筛选出华南区和华东区的数据

    df[(df['area']=='华南区') | (df['area']=='华东区')]
    
  3. 筛选出2024年1月的数据(假设有date列)

    df[(df['date']>='2024-01-01') & (df['date']<='2024-01-31')]
    
    
  4. 筛选出产品名包含"金"字的产品

    df[df['product_name'].str.contains('金')
    df[df['product_name'].str.startswith('金')
    

练习2:对比 SQL 和 pandas

把以下 SQL 翻译成 pandas

SELECT product_name, price, quantity

FROM sales

WHERE price > 100 AND quantity > 10

ORDER BY price DESC LIMIT 10

result = (
    df[(df["price"] > 100) & (df["quantity"] > 10)]
    .sort_values("price", ascending=False)
    .head(3)[["product_name", "price", "quantity"]]
)

print(result)

SELECT PdSalesMixDesc, Qty, NetSal

FROM ads_sap_sal

WHERE NetSal > 100 AND Qty > 10

ORDER BY Qty DESC LIMIT 10

result = (
	df[(df['NetSal']>100) & (df['Qty']>10])]
		.sort_values('Qty', ascending=False)
		.head(10)[['PdSalesMixDesc', 'Qty', 'NetSal']]
)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐