8人参与 • 2025-10-09 • 数据结构
dataframe是pandas库中最核心的数据结构,它以一种表格形式组织数据,类似于 excel 电子表格或 sql 数据库表。这种二维数据结构特别适合处理结构化数据。
本文介绍了pandas中dataframe的核心功能,包括创建、基本操作(查看、选择、过滤、修改)、常用功能(统计、缺失值处理、排序、分组聚合、应用自定义函数、数据结构转换)、合并与分割方法等。
从字典创建最直观,字典的键自动成为列名,值成为对应列的数据。适合数据已经按列组织好的情况。
import pandas as pd data = { 'name': ['alice', 'bob', 'charlie'], 'age': [25, 30, 35], 'city': ['new york', 'paris', 'london'] } df = pd.dataframe(data)
当数据是按行组织的记录时,这种方法更合适。需要显式指定列名,否则会自动生成数字列名(0,1,2…)。
data = [ ['alice', 25, 'new york'], # 第一个人的完整信息 ['bob', 30, 'paris'], # 第二个人的完整信息 ['charlie', 35, 'london'] # 第三个人的完整信息 ] # 将列表转换为dataframe,并指定列名 df = pd.dataframe(data, columns=['name', 'age', 'city'])
以下方法可以在不显示全部数据的情况下,快速了解dataframe的概况。
df.head() # 查看前5行 df.tail(3) # 查看后3行 df.shape # 查看维度(行数,列数) df.columns # 查看列名 df.dtypes # 查看每列数据类型
df['name'] # 选择单列,返回series对象 df[['name', 'age']] # 选择多列,返回新的dataframe df.loc[0] # 按标签选择第一行所有数据 df.iloc[0] # 按位置(索引)选择第一行所有数据
布尔索引是dataframe的筛选功能,可以使用复杂条件组合来精确选择所需数据。
df[df['age'] > 30] # 年龄大于30的记录 df[(df['age'] > 25) & (df['city'] == 'paris')] # 多条件筛选:年龄>25且城市为paris
dataframe的列操作可以像操作普通变量一样修改列数据。
df['age'] = df['age'] + 1 # 年龄列全部加1 df['new_column'] = range(3) # 添加新列
使用统计方法能快速了解数据的分布情况和基本特征。
df.info() # 快速查看dataframe的摘要信息,包括列名、非空值数量、数据类型等 df.describe() # 对数值列计算统计量(计数、均值、标准差等) df.mean(numeric_only=true) # 计算各数值列的均值 df['age'].value_counts() # 统计年龄列中每个值的出现次数
默认情况下只对数值列计算统计量,需要会对于非数值列计算,可以使用 include='all'
参数。
参数
df.describe( percentiles=none, # 指定要计算的分位数 include=none, # 指定包含的数据类型 exclude=none, # 指定排除的数据类型 datetime_is_numeric=false # 是否将datetime视为数值型 )
基本示例
import pandas as pd import numpy as np # 创建示例dataframe df = pd.dataframe({ '数值列': np.random.randn(100), '分类列': np.random.choice(['a', 'b', 'c'], 100), '缺失列': np.random.choice([1, 2, np.nan], 100) }) # 默认describe print(df.describe())
控制输出内容
# 只计算特定分位数 df.describe(percentiles=[0.1, 0.5, 0.9]) # 只包含数值列 df.describe(include=[np.number]) # 包含所有列 df.describe(include='all') # 排除数值列 df.describe(exclude=[np.number])
df.mean()
可以对 dataframe 或 series 中的数值数据计算算术平均值。
参数
df.mean( axis=0, # 计算方向:0-列方向,1-行方向 skipna=true, # 是否跳过nan值 numeric_only=true, # 是否只计算数值列 **kwargs # 其他参数 )
对dataframe使用
import pandas as pd df = pd.dataframe({ 'a': [1, 2, 3, 4], 'b': [1.5, 2.5, 3.5, 4.5], 'c': ['a', 'b', 'c', 'd'] # 非数值列 }) # 计算各列的平均值 print(df.mean())
对series使用
s = pd.series([10, 20, 30, 40]) print(s.mean()) # 输出: 25.0
常见场景
# 计算每列的平均值 column_means = df.mean() # 默认axis=0 # 计算每行的平均值 row_means = df.mean(axis=1) # 只计算数值列(推荐方式) df.mean(numeric_only=true)
df_with_nan = pd.dataframe({'a': [1, 2, np.nan, 4]}) # 跳过nan计算 df_with_nan.mean() # 输出a列平均值:(1+2+4)/3 ≈ 2.333 # 包含nan计算 df_with_nan.mean(skipna=false) # 输出nan
处理缺失值是数据清洗的重要步骤,根据情况选择删除或填充。
df.dropna() # 删除含缺失值的整行 df.fillna(0) # 用0填充缺失值 df.isna().sum() # 统计每列的缺失值数量
排序可以快速发现数据的极值等等。
df.sort_values('age', ascending=false) # 按年龄降序排列
分组聚合可以计算各组的统计量。
print(df.groupby('city')['age'].mean()) # 按城市分组计算平均年龄
对dataframe的行或列应用自定义函数。
df['age'].apply(lambda x: x * 2) # 对age列的值进行加倍
# 返回所有数据(不含列名)的二维列表。 data = df.values.tolist() # 提取某一列的数据,转换为列表。 names = df['name'].tolist()
# 默认返回 {列名: {索引: 值}} 的嵌套字典结构。 dict_data = df.to_dict() # 返回 [{列名: 值}, ...] 格式的字典列表,适合 json 转换。 dict_records = df.to_dict('records')
# 返回 dataframe 的 numpy 数组形式(不包含列名)。 numpy_array = df.to_numpy()
# 将 dataframe 转换为 json 字符串。 json_str = df.to_json() # 指定格式(orient 参数) json_records = df.to_json(orient='records')
concat是最简单的合并方法,适合结构相同的数据集简单拼接。
import pandas as pd # 创建示例dataframe df1 = pd.dataframe({'a': ['a0', 'a1', 'a2'], 'b': ['b0', 'b1', 'b2']}, index=[0, 1, 2]) df2 = pd.dataframe({'a': ['a3', 'a4', 'a5'], 'b': ['b3', 'b4', 'b5']}, index=[3, 4, 5]) # 纵向连接(默认axis=0) result = pd.concat([df1, df2]) # 横向连接 result_h = pd.concat([df1, df2], axis=1)
merge是基于列的合并,类似于sql的join操作,根据键值合并相关数据。
left = pd.dataframe({'key': ['k0', 'k1', 'k2'], 'a': ['a0', 'a1', 'a2'], 'b': ['b0', 'b1', 'b2']}) right = pd.dataframe({'key': ['k0', 'k1', 'k2', 'k3'], 'c': ['c0', 'c1', 'c2', 'c3'], 'd': ['d0', 'd1', 'd2', 'd3']}) # 内连接(默认) result = pd.merge(left, right, on='key') # 左连接 result_left = pd.merge(left, right, how='left', on='key') # 右连接 result_right = pd.merge(left, right, how='right', on='key') # 外连接 result_outer = pd.merge(left, right, how='outer', on='key')
join是基于索引的合并方法,适合索引有意义的场景。
left = pd.dataframe({'a': ['a0', 'a1', 'a2'], 'b': ['b0', 'b1', 'b2']}, index=['k0', 'k1', 'k2']) right = pd.dataframe({'c': ['c0', 'c1', 'c2'], 'd': ['d0', 'd1', 'd2']}, index=['k0', 'k1', 'k3']) # 左连接(默认) result = left.join(right) # 右连接 result_right = left.join(right, how='right') # 内连接 result_inner = left.join(right, how='inner') # 外连接 result_outer = left.join(right, how='outer')
当需要多个字段共同确定关联关系时,可以使用多键合并。
left = pd.dataframe({'key1': ['k0', 'k0', 'k1', 'k2'], 'key2': ['k0', 'k1', 'k0', 'k1'], 'a': ['a0', 'a1', 'a2', 'a3'], 'b': ['b0', 'b1', 'b2', 'b3']}) right = pd.dataframe({'key1': ['k0', 'k1', 'k1', 'k2'], 'key2': ['k0', 'k0', 'k0', 'k0'], 'c': ['c0', 'c1', 'c2', 'c3'], 'd': ['d0', 'd1', 'd2', 'd3']}) result = pd.merge(left, right, on=['key1', 'key2'])
当两个dataframe有相同列名但不是连接键时,添加后缀避免冲突。
# 合并时对重复列名添加后缀区分 result = pd.merge(left, right, on='key1', suffixes=('_left', '_right'))
indicator列会显示每行是来自"left_only"、“right_only"还是"both”,便于追踪合并结果。
# 合并后添加一列指示每行数据的来源 result = pd.merge(left, right, on='key1', how='outer', indicator=true)
行分割常用于将大数据集分成多个部分处理,或提取符合条件的子集。
# 创建示例dataframe df = pd.dataframe({'a': range(10), 'b': range(10, 20), 'c': range(20, 30)}) # 取前3行 df_head = df.head(3) # 取后3行 df_tail = df.tail(3) # 按位置分割 df_part1 = df.iloc[:5] # 前5行 df_part2 = df.iloc[5:] # 第6行到最后 # 按条件分割 df_filtered = df[df['a'] > 5] # a列大于5的行
列分割常用于特征选择,提取感兴趣的变量或特定类型的数据。
# 选择单列(返回series) col_a = df['a'] # 选择多列(返回dataframe) cols_ab = df[['a', 'b']] # 按数据类型选择:只选择数值型列 numeric_cols = df.select_dtypes(include=['number'])
随机分割常用于创建训练集和测试集,或进行随机抽样分析。
# 随机抽取30%的数据 df_sample = df.sample(frac=0.3) # 随机抽取固定数量(5行) df_sample_fixed = df.sample(n=5)
分组后分割可以让我们分别处理每个组的数据。
# 创建分组对象 grouped = df.groupby('a') # 获取特定组 group_5 = grouped.get_group(5) # 遍历所有组 for name, group in grouped: print(f"group {name}:") print(group)
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论