模块四-数据转换与操作——20. 数据排序
20. 数据排序
1. 概述
数据排序是数据分析中的基本操作,用于按特定列的值对数据进行升序或降序排列。Pandas 提供了sort_values()和sort_index()两种排序方法。
importpandasaspdimportnumpyasnp# 创建示例数据np.random.seed(42)df=pd.DataFrame({'姓名':['张三','李四','王五','赵六','钱七','孙八','周九','吴十'],'部门':['技术','销售','技术','市场','销售','技术','市场','销售'],'工资':[8000,12000,10000,15000,11000,9500,10500,12500],'年龄':[25,30,28,32,35,27,29,31],'入职日期':pd.date_range('2024-01-01',periods=8,freq='M')})print("原始数据:")print(df)2. 按值排序
2.1 sort_values() 基础
# 按单列升序(默认)print("按工资升序:")print(df.sort_values('工资'))# 按单列降序print("\n按工资降序:")print(df.sort_values('工资',ascending=False))2.2 按多列排序
# 先按部门升序,再按工资降序print("按部门升序、工资降序:")print(df.sort_values(['部门','工资'],ascending=[True,False]))# 多列排序示例print("\n按部门升序、年龄降序:")print(df.sort_values(['部门','年龄'],ascending=[True,False]))2.3 处理缺失值
# 创建包含缺失值的数据df_na=df.copy()df_na.loc[2,'工资']=np.nan df_na.loc[5,'年龄']=np.nanprint("包含缺失值的数据:")print(df_na)# na_position 控制缺失值位置print("\n缺失值放在最后:")print(df_na.sort_values('工资',na_position='last'))print("\n缺失值放在最前:")print(df_na.sort_values('工资',na_position='first'))3. 按索引排序
3.1 sort_index() 基础
# 创建乱序数据np.random.seed(42)df_shuffled=df.sample(frac=1)print("乱序数据:")print(df_shuffled)# 按行索引排序print("\n按行索引排序:")print(df_shuffled.sort_index())# 按行索引降序print("\n按行索引降序:")print(df_shuffled.sort_index(ascending=False))3.2 按列索引排序
# 按列索引排序(axis=1)print("按列索引排序:")print(df.sort_index(axis=1))# 按列索引降序print("\n按列索引降序:")print(df.sort_index(axis=1,ascending=False))4. 排序的高级应用
4.1 获取前 N 行
# 工资最高的3人print("工资最高的3人:")print(df.nlargest(3,'工资')[['姓名','工资']])# 工资最低的2人print("\n工资最低的2人:")print(df.nsmallest(2,'工资')[['姓名','工资']])# 按多列取最大print("\n年龄最大且工资最高的:")# 先按年龄排序,再取前3print(df.sort_values(['年龄','工资'],ascending=[False,False]).head(3))4.2 分组内排序
# 每个部门内按工资排序print("各部门内按工资排序:")print(df.sort_values(['部门','工资'],ascending=[True,False]))# 使用 groupby 后排序df_sorted=df.sort_values(['部门','工资'],ascending=[True,False])print("\n各部门工资排名:")print(df_sorted)4.3 排序后重置索引
# 排序后重置索引print("排序后重置索引:")df_sorted=df.sort_values('工资',ascending=False).reset_index(drop=True)print(df_sorted)# 保留原索引print("\n排序后保留原索引:")df_sorted_with_index=df.sort_values('工资',ascending=False).reset_index()print(df_sorted_with_index)5. 完整示例:销售数据分析
# 创建销售数据np.random.seed(42)sales=pd.DataFrame({'日期':pd.date_range('2024-01-01',periods=30,freq='D'),'产品':np.random.choice(['产品A','产品B','产品C'],30),'销售额':np.random.randint(1000,5000,30),'数量':np.random.randint(10,100,30),'地区':np.random.choice(['华东','华南','华北','西南'],30)})print("="*60)print("销售数据分析")print("="*60)print("\n原始数据:")print(sales.head(10))# 1. 按销售额排序(查看最高销售额)print("\n1. 销售额前5名:")print(sales.nlargest(5,'销售额')[['日期','产品','销售额']])# 2. 按日期排序print("\n2. 按日期排序:")print(sales.sort_values('日期').head(10)[['日期','销售额']])# 3. 按产品和销售额排序print("\n3. 按产品和销售额排序:")print(sales.sort_values(['产品','销售额'],ascending=[True,False]).head(10))# 4. 各地区销售额排名print("\n4. 各地区销售额排名(华东地区):")east_sales=sales[sales['地区']=='华东'].sort_values('销售额',ascending=False)print(east_sales[['日期','产品','销售额']])# 5. 按销售额排序后计算累计占比print("\n5. 销售额累计占比分析:")sales_sorted=sales.sort_values('销售额',ascending=False).reset_index(drop=True)sales_sorted['累计销售额']=sales_sorted['销售额'].cumsum()sales_sorted['累计占比']=(sales_sorted['累计销售额']/sales_sorted['销售额'].sum()*100).round(2)print(sales_sorted[['销售额','累计销售额','累计占比']].head(10))6. 排序性能优化
# 大数据集排序large_df=pd.DataFrame({'A':np.random.randint(0,100,100000),'B':np.random.randn(100000)})importtime# 单列排序start=time.time()large_df.sort_values('A',inplace=True)print(f"单列排序耗时:{time.time()-start:.4f}秒")# 多列排序start=time.time()large_df.sort_values(['A','B'],inplace=True)print(f"多列排序耗时:{time.time()-start:.4f}秒")7. 总结
| 方法 | 用途 | 示例 |
|---|---|---|
sort_values('col') | 按列升序排序 | df.sort_values('工资') |
sort_values('col', ascending=False) | 按列降序排序 | df.sort_values('工资', ascending=False) |
sort_values(['col1','col2']) | 按多列排序 | df.sort_values(['部门','工资']) |
sort_values(na_position='first') | 缺失值位置 | df.sort_values('col', na_position='first') |
nlargest(n, 'col') | 前 n 个最大值 | df.nlargest(3, '工资') |
nsmallest(n, 'col') | 前 n 个最小值 | df.nsmallest(3, '工资') |
sort_index() | 按索引排序 | df.sort_index() |
reset_index(drop=True) | 重置索引 | df.sort_values('col').reset_index(drop=True) |
