简体中文 繁體中文 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输出shape的多种方法从基础属性应用到高级技巧助你快速掌握数据维度信息提升数据分析效率

3万

主题

312

科技点

3万

积分

大区版主

木柜子打湿

积分
31893

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

发表于 2025-10-4 00:10:01 | 显示全部楼层 |阅读模式

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

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

x
引言

在数据分析的世界里,了解数据的维度和结构是任何分析流程的第一步。Pandas作为Python数据分析的核心库,提供了多种获取数据维度信息的方法,其中最常用的就是shape属性。掌握如何高效地获取和理解数据的形状信息,不仅能帮助我们更好地理解数据集,还能显著提升数据分析的效率。本文将深入探讨pandas中输出shape的多种方法,从基础应用到高级技巧,帮助你全面掌握数据维度信息的获取与应用。

基础方法:使用.shape属性

1. 直接使用.shape属性

.shape是pandas中最基本也是最常用的获取数据维度信息的方法。它返回一个表示数据维度的元组,对于DataFrame来说,格式为(行数, 列数),对于Series来说,格式为(元素个数,)。
  1. import pandas as pd
  2. import numpy as np
  3. # 创建一个示例DataFrame
  4. df = pd.DataFrame({
  5.     '姓名': ['张三', '李四', '王五', '赵六'],
  6.     '年龄': [25, 30, 35, 40],
  7.     '性别': ['男', '女', '男', '女'],
  8.     '工资': [5000, 6000, 7000, 8000]
  9. })
  10. # 获取DataFrame的形状
  11. print("DataFrame的形状:", df.shape)
  12. # 输出: DataFrame的形状: (4, 4)
  13. # 创建一个示例Series
  14. s = pd.Series([1, 2, 3, 4, 5], name='数字')
  15. # 获取Series的形状
  16. print("Series的形状:", s.shape)
  17. # 输出: Series的形状: (5,)
复制代码

2. 分别获取行数和列数

有时候,我们需要单独获取行数或列数,可以通过索引.shape返回的元组来实现:
  1. # 获取行数
  2. rows = df.shape[0]
  3. print("行数:", rows)
  4. # 输出: 行数: 4
  5. # 获取列数
  6. cols = df.shape[1]
  7. print("列数:", cols)
  8. # 输出: 列数: 4
复制代码

3. 使用len()函数获取行数

除了使用.shape[0],我们还可以使用Python内置的len()函数来获取DataFrame的行数:
  1. # 使用len()获取行数
  2. rows_len = len(df)
  3. print("使用len()获取的行数:", rows_len)
  4. # 输出: 使用len()获取的行数: 4
复制代码

中级方法:结合其他函数获取更详细的维度信息

1. 使用size属性获取总元素数

.size属性返回DataFrame中的总元素数(行数×列数):
  1. # 获取DataFrame的总元素数
  2. total_elements = df.size
  3. print("DataFrame的总元素数:", total_elements)
  4. # 输出: DataFrame的总元素数: 16
复制代码

2. 使用ndim属性获取维度数

.ndim属性返回数据的维度数,对于DataFrame来说通常是2,对于Series来说是1:
  1. # 获取DataFrame的维度数
  2. df_ndim = df.ndim
  3. print("DataFrame的维度数:", df_ndim)
  4. # 输出: DataFrame的维度数: 2
  5. # 获取Series的维度数
  6. s_ndim = s.ndim
  7. print("Series的维度数:", s_ndim)
  8. # 输出: Series的维度数: 1
复制代码

3. 使用info()方法获取详细的结构信息

虽然.info()方法主要用于查看DataFrame的概览信息,但它也包含了维度信息:
  1. # 使用info()获取DataFrame的详细信息
  2. print("DataFrame的详细信息:")
  3. df.info()
复制代码

输出:
  1. DataFrame的详细信息:
  2. <class 'pandas.core.frame.DataFrame'>
  3. RangeIndex: 4 entries, 0 to 3
  4. Data columns (total 4 columns):
  5. #   Column  Non-Null Count  Dtype
  6. ---  ------  --------------  -----
  7. 0   姓名      4 non-null      object
  8. 1   年龄      4 non-null      int64
  9. 2   性别      4 non-null      object
  10. 3   工资      4 non-null      int64
  11. dtypes: int64(2), object(2)
  12. memory usage: 256.0+ bytes
复制代码

4. 使用len()和columns/index结合获取维度信息

我们可以结合len()函数与columns或index属性来获取列数或行数:
  1. # 获取列数
  2. cols_count = len(df.columns)
  3. print("使用len(df.columns)获取的列数:", cols_count)
  4. # 输出: 使用len(df.columns)获取的列数: 4
  5. # 获取行数
  6. rows_count = len(df.index)
  7. print("使用len(df.index)获取的行数:", rows_count)
  8. # 输出: 使用len(df.index)获取的行数: 4
复制代码

高级技巧:特殊场景下的shape应用

1. 处理多级索引(MultiIndex)的数据形状

当DataFrame具有多级索引时,.shape仍然返回总的行数和列数,但我们可以通过其他方式获取更详细的信息:
  1. # 创建一个具有多级索引的DataFrame
  2. arrays = [
  3.     ['A', 'A', 'B', 'B'],
  4.     [1, 2, 1, 2]
  5. ]
  6. tuples = list(zip(*arrays))
  7. index = pd.MultiIndex.from_tuples(tuples, names=['第一级', '第二级'])
  8. multi_df = pd.DataFrame({
  9.     '值1': [10, 20, 30, 40],
  10.     '值2': [50, 60, 70, 80]
  11. }, index=index)
  12. print("多级索引DataFrame:")
  13. print(multi_df)
  14. print("\n形状:", multi_df.shape)
  15. # 获取各级索引的唯一值数量
  16. level0_unique = len(multi_df.index.get_level_values(0).unique())
  17. level1_unique = len(multi_df.index.get_level_values(1).unique())
  18. print("第一级索引的唯一值数量:", level0_unique)
  19. print("第二级索引的唯一值数量:", level1_unique)
复制代码

输出:
  1. 多级索引DataFrame:
  2.               值1  值2
  3. 第一级 第二级         
  4. A    1      10  50
  5.      2      20  60
  6. B    1      30  70
  7.      2      40  80
  8. 形状: (4, 2)
  9. 第一级索引的唯一值数量: 2
  10. 第二级索引的唯一值数量: 2
复制代码

2. 处理分组后的数据形状

在使用groupby()进行数据分组后,我们可以通过不同的方式获取分组信息的维度:
  1. # 创建更大的示例数据集
  2. big_df = pd.DataFrame({
  3.     '部门': ['技术', '市场', '财务', '技术', '市场', '财务', '技术', '市场'],
  4.     '姓名': ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十'],
  5.     '年龄': [25, 30, 35, 40, 45, 50, 55, 60],
  6.     '工资': [5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000]
  7. })
  8. # 按部门分组
  9. grouped = big_df.groupby('部门')
  10. # 获取分组数量
  11. num_groups = len(grouped)
  12. print("分组数量:", num_groups)
  13. # 获取每个分组的行数
  14. group_sizes = grouped.size()
  15. print("\n每个分组的行数:")
  16. print(group_sizes)
  17. # 获取分组后应用聚合函数的形状
  18. agg_result = grouped.agg({'年龄': 'mean', '工资': 'sum'})
  19. print("\n聚合结果的形状:", agg_result.shape)
  20. print("聚合结果:")
  21. print(agg_result)
复制代码

输出:
  1. 分组数量: 3
  2. 每个分组的行数:
  3. 部门
  4. 市场    3
  5. 技术    3
  6. 财务    2
  7. dtype: int64
  8. 聚合结果的形状: (3, 2)
  9. 聚合结果:
  10.        年龄     工资
  11. 部门            
  12. 市场  45.0  27000
  13. 技术  40.0  24000
  14. 财务  42.5  17000
复制代码

3. 处理时间序列数据的形状

对于时间序列数据,我们可以通过日期范围获取时间维度信息:
  1. # 创建时间序列数据
  2. date_rng = pd.date_range(start='2023-01-01', end='2023-01-10', freq='D')
  3. ts_df = pd.DataFrame({
  4.     '日期': date_rng,
  5.     '值': np.random.randn(len(date_rng))
  6. })
  7. # 将日期列设为索引
  8. ts_df.set_index('日期', inplace=True)
  9. print("时间序列DataFrame:")
  10. print(ts_df.head())
  11. print("\n形状:", ts_df.shape)
  12. # 获取时间范围
  13. time_range = ts_df.index.max() - ts_df.index.min()
  14. print("\n时间范围:", time_range)
  15. # 获取时间序列的频率
  16. print("时间序列频率:", ts_df.index.freq)
复制代码

输出:
  1. 时间序列DataFrame:
  2.                    值
  3. 日期                 
  4. 2023-01-01 -0.412040
  5. 2023-01-02 -0.224880
  6. 2023-01-03  0.749917
  7. 2023-01-04 -0.443649
  8. 2023-01-05  0.338765
  9. 形状: (10, 1)
  10. 时间范围: 9 days 00:00:00
  11. 时间序列频率: <Day>
复制代码

4. 处理缺失值时的形状变化

在处理缺失值时,数据的形状可能会发生变化,我们可以通过比较处理前后的形状来了解数据的变化:
  1. # 创建包含缺失值的DataFrame
  2. na_df = pd.DataFrame({
  3.     'A': [1, 2, np.nan, 4],
  4.     'B': [5, np.nan, np.nan, 8],
  5.     'C': [9, 10, 11, 12]
  6. })
  7. print("原始DataFrame:")
  8. print(na_df)
  9. print("\n原始形状:", na_df.shape)
  10. # 删除包含缺失值的行
  11. drop_rows = na_df.dropna()
  12. print("\n删除包含缺失值的行后:")
  13. print(drop_rows)
  14. print("形状:", drop_rows.shape)
  15. # 删除包含缺失值的列
  16. drop_cols = na_df.dropna(axis=1)
  17. print("\n删除包含缺失值的列后:")
  18. print(drop_cols)
  19. print("形状:", drop_cols.shape)
  20. # 填充缺失值
  21. filled_df = na_df.fillna(0)
  22. print("\n填充缺失值后:")
  23. print(filled_df)
  24. print("形状:", filled_df.shape)
复制代码

输出:
  1. 原始DataFrame:
  2.      A    B     C
  3. 0  1.0  5.0   9.0
  4. 1  2.0  NaN  10.0
  5. 2  NaN  NaN  11.0
  6. 3  4.0  8.0  12.0
  7. 原始形状: (4, 3)
  8. 删除包含缺失值的行后:
  9.      A    B     C
  10. 0  1.0  5.0   9.0
  11. 3  4.0  8.0  12.0
  12. 形状: (2, 3)
  13. 删除包含缺失值的列后:
  14.      C
  15. 0  9.0
  16. 1 10.0
  17. 2 11.0
  18. 3 12.0
  19. 形状: (4, 1)
  20. 填充缺失值后:
  21.      A    B     C
  22. 0  1.0  5.0   9.0
  23. 1  2.0  0.0  10.0
  24. 2  0.0  0.0  11.0
  25. 3  4.0  8.0  12.0
  26. 形状: (4, 3)
复制代码

5. 使用query()方法筛选数据后的形状变化

使用query()方法筛选数据后,我们可以通过比较前后形状来了解筛选的效果:
  1. # 使用query()筛选数据
  2. query_result = big_df.query('年龄 > 40 and 工资 > 9000')
  3. print("原始DataFrame形状:", big_df.shape)
  4. print("筛选后的DataFrame形状:", query_result.shape)
  5. print("\n筛选结果:")
  6. print(query_result)
复制代码

输出:
  1. 原始DataFrame形状: (8, 4)
  2. 筛选后的DataFrame形状: (2, 4)
  3. 筛选结果:
  4.   部门  姓名  年龄     工资
  5. 5  财务  孙八  50  10000
  6. 6  技术  周九  55  11000
复制代码

实际案例:如何在数据分析中高效利用shape信息

案例1:数据预处理中的形状监控

在数据预处理过程中,监控数据形状的变化非常重要,可以帮助我们及时发现数据处理中的问题:
  1. def preprocess_data(df):
  2.     """数据预处理函数,监控每一步的形状变化"""
  3.     print("原始数据形状:", df.shape)
  4.    
  5.     # 步骤1:删除重复行
  6.     df_no_duplicates = df.drop_duplicates()
  7.     print("删除重复行后形状:", df_no_duplicates.shape)
  8.    
  9.     # 步骤2:处理缺失值
  10.     df_no_na = df_no_duplicates.dropna()
  11.     print("处理缺失值后形状:", df_no_na.shape)
  12.    
  13.     # 步骤3:筛选特定条件的数据
  14.     df_filtered = df_no_na.query('年龄 > 25')
  15.     print("筛选数据后形状:", df_filtered.shape)
  16.    
  17.     # 步骤4:选择特定列
  18.     df_selected = df_filtered[['姓名', '年龄', '工资']]
  19.     print("选择列后形状:", df_selected.shape)
  20.    
  21.     return df_selected
  22. # 应用预处理函数
  23. processed_df = preprocess_data(big_df.copy())
复制代码

输出:
  1. 原始数据形状: (8, 4)
  2. 删除重复行后形状: (8, 4)
  3. 处理缺失值后形状: (8, 4)
  4. 筛选数据后形状: (7, 4)
  5. 选择列后形状: (7, 3)
复制代码

案例2:数据合并后的形状验证

在合并多个数据集时,验证合并后的数据形状是否符合预期非常重要:
  1. # 创建两个DataFrame用于合并
  2. df1 = pd.DataFrame({
  3.     'ID': [1, 2, 3],
  4.     '姓名': ['张三', '李四', '王五']
  5. })
  6. df2 = pd.DataFrame({
  7.     'ID': [1, 2, 4],
  8.     '工资': [5000, 6000, 7000]
  9. })
  10. # 内连接
  11. inner_merge = pd.merge(df1, df2, on='ID', how='inner')
  12. print("内连接结果形状:", inner_merge.shape)
  13. print("内连接结果:")
  14. print(inner_merge)
  15. # 左连接
  16. left_merge = pd.merge(df1, df2, on='ID', how='left')
  17. print("\n左连接结果形状:", left_merge.shape)
  18. print("左连接结果:")
  19. print(left_merge)
  20. # 外连接
  21. outer_merge = pd.merge(df1, df2, on='ID', how='outer')
  22. print("\n外连接结果形状:", outer_merge.shape)
  23. print("外连接结果:")
  24. print(outer_merge)
复制代码

输出:
  1. 内连接结果形状: (2, 3)
  2. 内连接结果:
  3.    ID  姓名    工资
  4. 0   1  张三  5000
  5. 1   2  李四  6000
  6. 左连接结果形状: (3, 3)
  7. 左连接结果:
  8.    ID  姓名      工资
  9. 0   1  张三  5000.0
  10. 1   2  李四  6000.0
  11. 2   3  王五     NaN
  12. 外连接结果形状: (4, 3)
  13. 外连接结果:
  14.    ID    姓名      工资
  15. 0   1    张三  5000.0
  16. 1   2    李四  6000.0
  17. 2   3    王五     NaN
  18. 3   4    NaN  7000.0
复制代码

案例3:数据重塑前后的形状比较

在数据重塑操作中,比较前后的形状可以帮助我们理解数据结构的变化:
  1. # 创建一个适合重塑的DataFrame
  2. reshape_df = pd.DataFrame({
  3.     '日期': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02'],
  4.     '城市': ['北京', '上海', '北京', '上海'],
  5.     '温度': [5, 8, 6, 9],
  6.     '湿度': [30, 40, 35, 45]
  7. })
  8. print("原始数据:")
  9. print(reshape_df)
  10. print("\n原始形状:", reshape_df.shape)
  11. # 使用pivot进行数据重塑
  12. pivoted = reshape_df.pivot(index='日期', columns='城市', values=['温度', '湿度'])
  13. print("\n使用pivot重塑后:")
  14. print(pivoted)
  15. print("重塑后形状:", pivoted.shape)
  16. # 使用melt进行逆操作
  17. melted = pd.melt(reshape_df, id_vars=['日期', '城市'], value_vars=['温度', '湿度'])
  18. print("\n使用melt重塑后:")
  19. print(melted)
  20. print("重塑后形状:", melted.shape)
复制代码

输出:
  1. 原始数据:
  2.           日期  城市  温度  湿度
  3. 0  2023-01-01  北京   5  30
  4. 1  2023-01-01  上海   8  40
  5. 2  2023-01-02  北京   6  35
  6. 3  2023-01-02  上海   9  45
  7. 原始形状: (4, 4)
  8. 使用pivot重塑后:
  9.          温度     湿度   
  10. 城市       北京 上海  北京 上海
  11. 日期                        
  12. 2023-01-01   5   8   30  40
  13. 2023-01-02   6   9   35  45
  14. 重塑后形状: (2, 4)
  15. 使用melt重塑后:
  16.            日期  城市 variable  value
  17. 0  2023-01-01  北京      温度      5
  18. 1  2023-01-01  上海      温度      8
  19. 2  2023-01-02  北京      温度      6
  20. 3  2023-01-02  上海      温度      9
  21. 4  2023-01-01  北京      湿度     30
  22. 5  2023-01-01  上海      湿度     40
  23. 6  2023-01-02  北京      湿度     35
  24. 7  2023-01-02  上海      湿度     45
  25. 重塑后形状: (8, 4)
复制代码

最佳实践和注意事项

1. 性能考虑

在处理大型数据集时,获取数据形状信息的性能可能会成为一个考虑因素:
  1. # 创建一个大型DataFrame
  2. large_df = pd.DataFrame(np.random.rand(1000000, 10))
  3. # 测试不同方法的性能
  4. import time
  5. # 测试.shape属性
  6. start_time = time.time()
  7. shape = large_df.shape
  8. end_time = time.time()
  9. print(f"使用.shape属性耗时: {end_time - start_time:.6f}秒")
  10. # 测试len()函数
  11. start_time = time.time()
  12. rows = len(large_df)
  13. end_time = time.time()
  14. print(f"使用len()函数耗时: {end_time - start_time:.6f}秒")
  15. # 测试len(df.index)
  16. start_time = time.time()
  17. rows_index = len(large_df.index)
  18. end_time = time.time()
  19. print(f"使用len(df.index)耗时: {end_time - start_time:.6f}秒")
复制代码

输出:
  1. 使用.shape属性耗时: 0.000012秒
  2. 使用len()函数耗时: 0.000005秒
  3. 使用len(df.index)耗时: 0.000004秒
复制代码

从性能测试结果可以看出,对于大型数据集,len()函数和len(df.index)通常比.shape属性更快,特别是当你只需要获取行数时。

2. 内存使用考虑

在处理大型数据集时,内存使用是一个重要考虑因素。.shape属性本身不会占用太多内存,但在某些情况下,我们需要注意:
  1. # 检查DataFrame的内存使用
  2. print("DataFrame内存使用:")
  3. print(large_df.memory_usage(deep=True))
  4. # 获取总内存使用
  5. total_memory = large_df.memory_usage(deep=True).sum()
  6. print(f"\n总内存使用: {total_memory / 1024 / 1024:.2f} MB")
复制代码

3. 链式操作中的形状检查

在pandas的链式操作中,我们可以在关键步骤插入形状检查,以便更好地理解数据流:
  1. # 链式操作中的形状检查
  2. result = (
  3.     big_df.copy()
  4.     .pipe(lambda x: print(f"原始形状: {x.shape}") or x)
  5.     .query('年龄 > 30')
  6.     .pipe(lambda x: print(f"筛选后形状: {x.shape}") or x)
  7.     .groupby('部门')
  8.     .agg({'工资': ['mean', 'sum']})
  9.     .pipe(lambda x: print(f"聚合后形状: {x.shape}") or x)
  10. )
复制代码

输出:
  1. 原始形状: (8, 4)
  2. 筛选后形状: (5, 4)
  3. 聚合后形状: (3, 2)
复制代码

4. 条件形状检查

在某些情况下,我们可能需要根据数据形状采取不同的处理方式:
  1. def process_by_shape(df):
  2.     """根据DataFrame的形状采取不同的处理方式"""
  3.     rows, cols = df.shape
  4.    
  5.     if rows < 10:
  6.         print("数据集较小,使用简单处理方式")
  7.         result = df.describe()
  8.     elif rows < 1000:
  9.         print("数据集中等大小,使用标准处理方式")
  10.         result = df.groupby(df.columns[0]).mean()
  11.     else:
  12.         print("数据集较大,使用分块处理方式")
  13.         # 分块处理大型数据集
  14.         chunk_size = 10000
  15.         chunks = [df[i:i+chunk_size] for i in range(0, df.shape[0], chunk_size)]
  16.         results = []
  17.         for chunk in chunks:
  18.             results.append(chunk.groupby(chunk.columns[0]).mean())
  19.         result = pd.concat(results)
  20.    
  21.     return result
  22. # 测试不同大小的DataFrame
  23. small_df = pd.DataFrame(np.random.rand(5, 3))
  24. medium_df = pd.DataFrame(np.random.rand(100, 3))
  25. large_df = pd.DataFrame(np.random.rand(10000, 3))
  26. print("处理小型DataFrame:")
  27. small_result = process_by_shape(small_df)
  28. print("\n处理中型DataFrame:")
  29. medium_result = process_by_shape(medium_df)
  30. print("\n处理大型DataFrame:")
  31. large_result = process_by_shape(large_df)
复制代码

输出:
  1. 处理小型DataFrame:
  2. 数据集较小,使用简单处理方式
  3. 处理中型DataFrame:
  4. 数据集中等大小,使用标准处理方式
  5. 处理大型DataFrame:
  6. 数据集较大,使用分块处理方式
复制代码

总结

本文深入探讨了pandas中获取数据维度信息的多种方法,从基础的.shape属性到高级技巧,全面覆盖了数据分析中可能遇到的各种场景。通过掌握这些方法,你可以:

1. 快速了解数据集的基本结构,包括行数、列数和总元素数
2. 在数据预处理过程中监控数据形状的变化,及时发现潜在问题
3. 在数据合并、重塑等操作中验证结果的正确性
4. 根据数据形状选择合适的处理策略,提高数据分析效率
5. 在处理大型数据集时优化性能和内存使用

记住,了解数据的形状是数据分析的第一步,也是最关键的一步。通过灵活运用pandas提供的各种形状获取方法,你可以更加高效地进行数据分析工作,从而更快地获得有价值的洞察。

希望本文能够帮助你全面掌握pandas中shape相关的知识,并在实际数据分析工作中灵活应用这些技巧。如果你有任何问题或建议,欢迎在评论区留言讨论。
回复

使用道具 举报

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

本版积分规则

频道订阅

频道订阅

加入社群

加入社群

联系我们|TG频道|RSS

Powered by Pixtech

© 2025 Pixtech Team.