简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français

站内搜索

搜索

活动公告

11-02 12:46
10-23 09:32
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,将及时处理!
10-23 09:31
10-23 09:28
通知:签到时间调整为每日4:00(东八区)
10-23 09:26

轻松掌握pandas输出形状技巧提升数据分析效率

3万

主题

323

科技点

3万

积分

大区版主

木柜子打湿

积分
31894

财Doro三倍冰淇淋无人之境【一阶】立华奏小樱(小丑装)⑨的冰沙以外的星空【二阶】

发表于 2025-10-3 09:20:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. pandas shape基础介绍

在数据分析的世界里,了解数据集的规模是首要任务之一。pandas作为Python数据分析的核心库,提供了shape属性,让我们能够快速获取数据集的维度信息。shape属性返回一个元组,表示DataFrame或Series的维度,对于DataFrame,它返回(行数, 列数),而对于一维的Series,则返回(元素数,)。

shape属性是pandas中最基础但也是最常用的属性之一。无论是数据清洗、数据转换还是数据分析,了解数据的形状都是必不可少的一步。通过shape,我们可以快速了解数据集的大小,判断数据是否加载正确,以及在进行各种操作后验证数据的维度变化。

2. 如何使用shape属性

使用shape属性非常简单,只需在DataFrame或Series对象后加上.shape即可。让我们通过一些示例来详细了解:
  1. import pandas as pd
  2. import numpy as np
  3. # 创建一个简单的DataFrame
  4. data = {'Name': ['Alice', 'Bob', 'Charlie', 'David'],
  5.         'Age': [25, 30, 35, 40],
  6.         'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']}
  7. df = pd.DataFrame(data)
  8. # 获取DataFrame的形状
  9. print("DataFrame的形状:", df.shape)
  10. # 输出: DataFrame的形状: (4, 3)
  11. # 创建一个Series
  12. s = pd.Series([1, 2, 3, 4, 5])
  13. # 获取Series的形状
  14. print("Series的形状:", s.shape)
  15. # 输出: Series的形状: (5,)
复制代码

shape返回的是一个元组,我们可以分别获取行数和列数:
  1. # 获取行数
  2. rows = df.shape[0]
  3. print("行数:", rows)  # 输出: 行数: 4
  4. # 获取列数
  5. cols = df.shape[1]
  6. print("列数:", cols)  # 输出: 列数: 3
复制代码

这种分离获取行列数的方式在后续的数据处理中非常有用,特别是在循环或条件判断中。

3. shape在实际数据分析中的应用场景

shape属性在数据分析的各个阶段都有广泛的应用,以下是几个常见的应用场景:

3.1 数据加载验证

在加载数据后,我们通常需要确认数据是否正确加载:
  1. # 从CSV文件加载数据
  2. df = pd.read_csv('large_dataset.csv')
  3. # 检查数据形状
  4. print("数据集形状:", df.shape)
  5. # 预期数据集应该有10000行和20列
  6. if df.shape != (10000, 20):
  7.     print("警告: 数据集形状不符合预期!")
  8. else:
  9.     print("数据集加载成功!")
复制代码

3.2 数据清洗后的验证

数据清洗过程中,我们可能会删除一些行或列,使用shape可以验证操作是否按预期进行:
  1. # 原始数据形状
  2. print("原始数据形状:", df.shape)
  3. # 删除含有缺失值的行
  4. df_cleaned = df.dropna()
  5. # 清洗后数据形状
  6. print("清洗后数据形状:", df_cleaned.shape)
  7. # 计算删除的行数
  8. removed_rows = df.shape[0] - df_cleaned.shape[0]
  9. print(f"删除了 {removed_rows} 行含有缺失值的数据")
复制代码

3.3 数据分割验证

在机器学习中,我们经常需要将数据集分为训练集和测试集,shape可以帮助我们验证分割是否正确:
  1. from sklearn.model_selection import train_test_split
  2. # 假设df是我们的数据集
  3. X = df.drop('target', axis=1)  # 特征
  4. y = df['target']  # 目标变量
  5. # 将数据分为训练集和测试集,比例为7:3
  6. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
  7. # 验证分割结果
  8. print("训练集特征形状:", X_train.shape)
  9. print("测试集特征形状:", X_test.shape)
  10. print("训练集目标形状:", y_train.shape)
  11. print("测试集目标形状:", y_test.shape)
  12. # 检查分割比例是否正确
  13. train_ratio = X_train.shape[0] / df.shape[0]
  14. test_ratio = X_test.shape[0] / df.shape[0]
  15. print(f"训练集比例: {train_ratio:.2f}")
  16. print(f"测试集比例: {test_ratio:.2f}")
复制代码

4. 结合shape使用的高效技巧

除了基本的使用方法,还有一些结合shape的高效技巧可以提升我们的数据分析效率:

4.1 条件筛选后的数据量统计

我们可以使用shape来快速统计满足特定条件的数据量:
  1. # 假设我们有一个包含销售数据的DataFrame
  2. sales_data = pd.DataFrame({
  3.     'Product': ['A', 'B', 'A', 'C', 'B', 'A'],
  4.     'Sales': [100, 150, 200, 50, 300, 250],
  5.     'Region': ['North', 'South', 'East', 'West', 'North', 'South']
  6. })
  7. # 统计产品A的销售记录数量
  8. product_a_count = sales_data[sales_data['Product'] == 'A'].shape[0]
  9. print(f"产品A的销售记录数量: {product_a_count}")
  10. # 统计销售额超过200的记录数量
  11. high_sales_count = sales_data[sales_data['Sales'] > 200].shape[0]
  12. print(f"销售额超过200的记录数量: {high_sales_count}")
  13. # 统计北部地区且销售额超过100的记录数量
  14. north_high_sales_count = sales_data[(sales_data['Region'] == 'North') & (sales_data['Sales'] > 100)].shape[0]
  15. print(f"北部地区且销售额超过100的记录数量: {north_high_sales_count}")
复制代码

4.2 动态调整数据结构

有时我们需要根据数据的形状动态调整数据处理逻辑:
  1. def process_data(df):
  2.     # 根据数据形状选择不同的处理方式
  3.     if df.shape[1] > 10:  # 如果列数超过10
  4.         print("数据集列数较多,使用降维处理...")
  5.         # 这里可以添加降维代码
  6.     elif df.shape[0] > 10000:  # 如果行数超过10000
  7.         print("数据集行数较多,使用分批处理...")
  8.         # 这里可以添加分批处理代码
  9.     else:
  10.         print("数据集规模适中,使用常规处理...")
  11.         # 这里可以添加常规处理代码
  12.    
  13.     return df
  14. # 测试函数
  15. large_df = pd.DataFrame(np.random.rand(15000, 5))  # 15000行5列的数据
  16. process_data(large_df)
  17. wide_df = pd.DataFrame(np.random.rand(100, 15))  # 100行15列的数据
  18. process_data(wide_df)
复制代码

4.3 内存使用优化

对于大型数据集,我们可以根据shape来优化内存使用:
  1. def optimize_memory(df):
  2.     # 获取数据形状
  3.     rows, cols = df.shape
  4.    
  5.     # 如果数据集很大,考虑使用更高效的数据类型
  6.     if rows > 1000000:  # 超过100万行
  7.         print("检测到大型数据集,优化内存使用...")
  8.         
  9.         # 遍历每一列
  10.         for col in df.columns:
  11.             col_type = df[col].dtype
  12.             
  13.             # 如果是整数类型
  14.             if col_type == 'int64':
  15.                 # 检查值的范围,使用最小够用的整数类型
  16.                 col_min = df[col].min()
  17.                 col_max = df[col].max()
  18.                
  19.                 if col_min > np.iinfo(np.int8).min and col_max < np.iinfo(np.int8).max:
  20.                     df[col] = df[col].astype(np.int8)
  21.                 elif col_min > np.iinfo(np.int16).min and col_max < np.iinfo(np.int16).max:
  22.                     df[col] = df[col].astype(np.int16)
  23.                 elif col_min > np.iinfo(np.int32).min and col_max < np.iinfo(np.int32).max:
  24.                     df[col] = df[col].astype(np.int32)
  25.             
  26.             # 如果是浮点数类型
  27.             elif col_type == 'float64':
  28.                 df[col] = df[col].astype(np.float32)
  29.    
  30.     return df
  31. # 创建一个大型DataFrame
  32. large_df = pd.DataFrame({
  33.     'id': range(1, 2000000),
  34.     'value': np.random.rand(2000000),
  35.     'category': np.random.choice(['A', 'B', 'C', 'D'], size=2000000)
  36. })
  37. # 优化前内存使用
  38. print("优化前内存使用:", large_df.memory_usage(deep=True).sum() / 1024**2, "MB")
  39. # 优化内存
  40. optimized_df = optimize_memory(large_df.copy())
  41. # 优化后内存使用
  42. print("优化后内存使用:", optimized_df.memory_usage(deep=True).sum() / 1024**2, "MB")
复制代码

5. shape与其他pandas功能的结合使用

shape属性可以与pandas的其他功能结合使用,发挥更大的威力:

5.1 与groupby结合使用

我们可以使用shape来统计分组后的数据量:
  1. # 创建一个示例DataFrame
  2. df = pd.DataFrame({
  3.     'Department': ['HR', 'IT', 'Finance', 'HR', 'IT', 'Finance', 'HR'],
  4.     'Employee': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank', 'Grace'],
  5.     'Salary': [70000, 80000, 90000, 75000, 85000, 95000, 72000]
  6. })
  7. # 按部门分组并统计每个部门的员工数量
  8. dept_counts = df.groupby('Department').size()
  9. print("每个部门的员工数量:")
  10. print(dept_counts)
  11. # 使用shape获取每个部门的员工数量
  12. dept_counts_shape = df.groupby('Department').apply(lambda x: x.shape[0])
  13. print("\n使用shape统计的每个部门的员工数量:")
  14. print(dept_counts_shape)
复制代码

5.2 与pivot_table结合使用

在创建透视表后,我们可以使用shape来了解透视表的维度:
  1. # 创建一个更复杂的示例DataFrame
  2. df = pd.DataFrame({
  3.     'Date': pd.date_range(start='2023-01-01', periods=12, freq='M'),
  4.     'Product': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
  5.     'Region': ['North', 'North', 'South', 'South', 'East', 'East', 'West', 'West', 'North', 'North', 'South', 'South'],
  6.     'Sales': [100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650]
  7. })
  8. # 创建透视表
  9. pivot = pd.pivot_table(df, values='Sales', index='Product', columns='Region', aggfunc='sum')
  10. # 查看透视表的形状
  11. print("透视表的形状:", pivot.shape)
  12. print("透视表内容:")
  13. print(pivot)
  14. # 检查透视表是否为空
  15. if pivot.shape == (0, 0):
  16.     print("警告: 透视表为空!")
  17. else:
  18.     print("透视表创建成功!")
复制代码

5.3 与concat/merge结合使用

在合并或连接数据后,我们可以使用shape来验证操作结果:
  1. # 创建两个DataFrame
  2. df1 = pd.DataFrame({
  3.     'ID': [1, 2, 3],
  4.     'Name': ['Alice', 'Bob', 'Charlie']
  5. })
  6. df2 = pd.DataFrame({
  7.     'ID': [4, 5, 6],
  8.     'Name': ['David', 'Eve', 'Frank']
  9. })
  10. # 垂直合并(行合并)
  11. concat_vertical = pd.concat([df1, df2], axis=0)
  12. print("垂直合并后的形状:", concat_vertical.shape)
  13. print("垂直合并结果:")
  14. print(concat_vertical)
  15. # 创建另外两个DataFrame用于水平合并
  16. df3 = pd.DataFrame({
  17.     'ID': [1, 2, 3],
  18.     'Name': ['Alice', 'Bob', 'Charlie']
  19. })
  20. df4 = pd.DataFrame({
  21.     'Age': [25, 30, 35],
  22.     'City': ['New York', 'Los Angeles', 'Chicago']
  23. })
  24. # 水平合并(列合并)
  25. concat_horizontal = pd.concat([df3, df4], axis=1)
  26. print("\n水平合并后的形状:", concat_horizontal.shape)
  27. print("水平合并结果:")
  28. print(concat_horizontal)
  29. # 使用merge进行合并
  30. df5 = pd.DataFrame({
  31.     'ID': [1, 2, 3],
  32.     'Salary': [50000, 60000, 70000]
  33. })
  34. merge_result = pd.merge(df3, df5, on='ID')
  35. print("\n合并后的形状:", merge_result.shape)
  36. print("合并结果:")
  37. print(merge_result)
复制代码

6. 实际案例分析

让我们通过一个实际的数据分析案例来综合运用shape属性的各种技巧:
  1. # 假设我们有一个销售数据集
  2. # 首先创建一个模拟数据集
  3. np.random.seed(42)
  4. dates = pd.date_range(start='2022-01-01', end='2022-12-31')
  5. products = ['A', 'B', 'C', 'D', 'E']
  6. regions = ['North', 'South', 'East', 'West']
  7. # 生成随机销售数据
  8. data = []
  9. for date in dates:
  10.     for product in products:
  11.         for region in regions:
  12.             sales = np.random.randint(100, 1000)
  13.             data.append([date, product, region, sales])
  14. sales_df = pd.DataFrame(data, columns=['Date', 'Product', 'Region', 'Sales'])
  15. # 查看数据集的基本信息
  16. print("数据集形状:", sales_df.shape)
  17. print("前5行数据:")
  18. print(sales_df.head())
  19. # 1. 数据清洗
  20. # 检查是否有缺失值
  21. print("\n缺失值统计:")
  22. print(sales_df.isnull().sum())
  23. # 假设我们发现有一些异常值(销售额为0)
  24. zero_sales = sales_df[sales_df['Sales'] == 0]
  25. print(f"\n销售额为0的记录数量: {zero_sales.shape[0]}")
  26. # 删除销售额为0的记录
  27. sales_df_cleaned = sales_df[sales_df['Sales'] > 0]
  28. print(f"清洗后的数据集形状: {sales_df_cleaned.shape}")
  29. # 2. 数据分析
  30. # 按产品统计总销售额和销售次数
  31. product_stats = sales_df_cleaned.groupby('Product').agg({
  32.     'Sales': ['sum', 'mean', 'count']
  33. })
  34. print("\n产品统计:")
  35. print(product_stats)
  36. # 使用shape获取每个产品的销售次数
  37. product_counts = sales_df_cleaned.groupby('Product').apply(lambda x: x.shape[0])
  38. print("\n每个产品的销售次数:")
  39. print(product_counts)
  40. # 3. 数据可视化准备
  41. # 按月份和地区汇总销售额
  42. sales_df_cleaned['Month'] = sales_df_cleaned['Date'].dt.month
  43. monthly_region_sales = pd.pivot_table(
  44.     sales_df_cleaned,
  45.     values='Sales',
  46.     index='Month',
  47.     columns='Region',
  48.     aggfunc='sum'
  49. )
  50. print("\n月度地区销售额透视表形状:", monthly_region_sales.shape)
  51. print("月度地区销售额透视表:")
  52. print(monthly_region_sales)
  53. # 4. 高级分析
  54. # 计算每个产品在每个地区的市场份额
  55. region_product_sales = pd.pivot_table(
  56.     sales_df_cleaned,
  57.     values='Sales',
  58.     index='Region',
  59.     columns='Product',
  60.     aggfunc='sum'
  61. )
  62. # 计算每个地区的总销售额
  63. region_total = region_product_sales.sum(axis=1)
  64. # 计算市场份额
  65. market_share = region_product_sales.div(region_total, axis=0) * 100
  66. print("\n市场份额表形状:", market_share.shape)
  67. print("市场份额(%):")
  68. print(market_share)
  69. # 5. 数据导出准备
  70. # 假设我们只想要销售额前80%的数据
  71. # 首先按销售额排序
  72. sales_df_sorted = sales_df_cleaned.sort_values('Sales', ascending=False)
  73. # 计算前80%的数据应该有多少行
  74. top_80_percent_rows = int(sales_df_sorted.shape[0] * 0.8)
  75. # 获取前80%的数据
  76. top_80_percent_data = sales_df_sorted.head(top_80_percent_rows)
  77. print(f"\n前80%高销售额数据形状: {top_80_percent_data.shape}")
  78. print(f"前80%高销售额数据占总销售额的比例: {top_80_percent_data['Sales'].sum() / sales_df_cleaned['Sales'].sum() * 100:.2f}%")
  79. # 6. 性能优化
  80. # 如果数据集很大,我们可以考虑使用更高效的数据类型
  81. def optimize_dataframe(df):
  82.     # 获取原始内存使用
  83.     original_memory = df.memory_usage(deep=True).sum() / 1024**2
  84.    
  85.     # 优化数值列
  86.     for col in df.select_dtypes(include=['int64']).columns:
  87.         df[col] = pd.to_numeric(df[col], downcast='integer')
  88.    
  89.     for col in df.select_dtypes(include=['float64']).columns:
  90.         df[col] = pd.to_numeric(df[col], downcast='float')
  91.    
  92.     # 优化对象列
  93.     for col in df.select_dtypes(include=['object']).columns:
  94.         if df[col].nunique() / len(df[col]) < 0.5:  # 如果唯一值比例小于50%
  95.             df[col] = df[col].astype('category')
  96.    
  97.     # 获取优化后的内存使用
  98.     optimized_memory = df.memory_usage(deep=True).sum() / 1024**2
  99.    
  100.     print(f"原始内存使用: {original_memory:.2f} MB")
  101.     print(f"优化后内存使用: {optimized_memory:.2f} MB")
  102.     print(f"内存减少: {(original_memory - optimized_memory) / original_memory * 100:.2f}%")
  103.    
  104.     return df
  105. # 优化数据框
  106. print("\n数据框优化:")
  107. optimized_sales_df = optimize_dataframe(sales_df_cleaned.copy())
复制代码

这个案例展示了如何在实际数据分析过程中使用shape属性来:

1. 验证数据加载和清洗的结果
2. 统计分组数据的数量
3. 检查透视表的维度
4. 确定数据子集的大小
5. 监控内存优化效果

7. 总结

pandas的shape属性虽然简单,但在数据分析中却是一个不可或缺的工具。通过本文的介绍,我们了解了shape属性的基本用法、应用场景以及与其他pandas功能的结合使用。掌握shape属性的使用技巧,可以帮助我们:

1. 快速了解数据集的规模和结构
2. 验证数据操作的结果是否符合预期
3. 优化数据处理流程和内存使用
4. 提高数据分析的效率和准确性

在实际的数据分析工作中,建议将检查数据形状作为一个标准步骤,特别是在数据加载、清洗、转换和合并等关键操作之后。这样可以帮助我们及时发现问题,确保数据分析的准确性和可靠性。

通过不断实践和探索,你会发现shape属性虽然简单,但在提升数据分析效率方面有着不可替代的作用。希望本文的介绍能够帮助你更好地掌握pandas输出形状技巧,提升数据分析效率。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

频道订阅

频道订阅

加入社群

加入社群

联系我们|TG频道|RSS

Powered by Pixtech

© 2025 Pixtech Team.