官方文档 https://pandas.pydata.org/docs/index.html
数据集 #
列几个数据集用于测试:
- https://learn.microsoft.com/en-us/power-bi/create-reports/sample-financial-download (Financial.xlsx)
- https://www.gairuo.com/file/data/dataset/team.xlsx (team.xlsx)
查看数据 #
df.head() # 头部 5 条
df.tail() # 尾部 5 条
df.sample() # 随机查看 5 条
df.shape # (100, 6) 查看行数和列数
df.info() # 查看索引、数据类型和内存信息
df.describe() # 查看数值型列的汇总统计
df.dtypes # 查看各字段类型
df.axes # 显示数据行和列名
df.columns # 列名
选取数据 #
选择列 #
df["Q1"] # 指定列
df.Q1 # 同上一行
df[['team', 'Q1']] # 只看这两列
df.loc[:, ['team', 'Q1']] # 同上一行
选择行 #
df[df.index == 'Liver'] # 根据索引名称
# 根据自然索引
df[0:3] # 取前三个
df[0:10:2] # 前 10 个每隔两个取一个
df.iloc[:10, :] # 前 10 个
指定行和列 #
df.loc['Ben', 'Q1':'Q4']
df.loc['A': 'D', 'Q1': 'Q4']
条件选择 #
df[df.Q1 > 90] # Q1 大于 90 的
df[df.team == 'C'] # team 列为 'C' 的
df[df.index == 'Oscar'] # 指定 index 名称
运算数据 #
排序 #
df.sort_values(by="Q1", ascending=False) # 按 Q1 降序排列, default is True
分组聚合 #
df.groupby('team').sum() # 求和
df.groupby('team').mean() # 求平均
df.groupby('team').agg({'Q1': sum, 'Q2': count, 'Q3': 'mean', 'Q4': max}) # agg 很强大
数据反转 #
df.T
应该能玩出花。
数据降维 #
df.groupby('team').sum().stack()
df.groupby('team').sum().unstack()
举个例子:
>>> df_single_level_cols
weight height
cat 0 1
dog 2 3
>>> df_single_level_cols.stack()
cat weight 0
height 1
dog weight 2
height 3
dtype: int64
数据统计 #
df.mean()
df.corr() # 返回列与列之间的相关系数
df.max()
df.min()
df.std() # 标准差
df.var() # 方差
df.mode() # 众数
df.median() # 中位数
绘图 #
df.plot()
导出 #
支持 CSV 、 Excel 、 HTML 等常见格式。
MultiIndex #
参考 #
Pandas 常用操作:数据筛选、查询与更新 #
Pandas 是 Python 中最强大的数据处理库之一,特别擅长数据筛选、查询和更新操作。以下是一些常用场景和技巧。
1. 数据筛选与查询 #
1.1 基本条件筛选 #
import pandas as pd
import numpy as np
# 创建示例 DataFrame
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
'age': [25, 30, 35, 40, 45],
'city': ['New York', 'London', 'Paris', 'Tokyo', 'Berlin'],
'salary': [50000, 60000, 70000, 80000, 90000],
'department': ['IT', 'HR', 'IT', 'Finance', 'HR']
})
# 1. 简单条件筛选
young_employees = df[df['age'] < 35]
it_employees = df[df['department'] == 'IT']
# 2. 多条件筛选
it_young = df[(df['department'] == 'IT') & (df['age'] < 40)]
hr_or_finance = df[(df['department'] == 'HR') | (df['department'] == 'Finance')]
# 3. 使用 isin 进行多值筛选
selected_cities = df[df['city'].isin(['New York', 'Paris', 'Berlin'])]
# 4. 使用 query 方法
high_salary = df.query('salary > 65000 and age > 30')
1.2 字符串筛选 #
# 1. 字符串包含
names_with_a = df[df['name'].str.contains('a')]
# 2. 字符串开头/结尾
names_starting_with_a = df[df['name'].str.startswith('A')]
names_ending_with_e = df[df['name'].str.endswith('e')]
# 3. 正则表达式匹配
names_with_vowel_ending = df[df['name'].str.contains('[aeiou]$', regex=True)]
1.3 基于索引的筛选 #
# 1. 按位置选择
first_three = df.iloc[:3] # 前3行
specific_rows = df.iloc[[0, 2, 4]] # 第0,2,4行
# 2. 按标签选择
df_indexed = df.set_index('name')
alice_info = df_indexed.loc['Alice']
multiple_people = df_indexed.loc[['Alice', 'Charlie', 'Eva']]
2. 数据更新操作 #
2.1 修改列值 #
# 1. 直接修改列
df['salary'] = df['salary'] * 1.1 # 给所有人加薪10%
# 2. 条件更新
df.loc[df['department'] == 'IT', 'salary'] = df['salary'] * 1.15 # IT部门加薪15%
# 3. 使用 apply 函数
df['age_group'] = df['age'].apply(
lambda x: 'Young' if x < 30 else 'Middle-aged' if x < 45 else 'Senior'
)
# 4. 使用 np.where
df['bonus'] = np.where(df['salary'] > 70000, 5000, 3000)
2.2 添加新列 #
# 1. 基于计算
df['annual_bonus'] = df['salary'] * 0.1
# 2. 基于多列计算
df['total_compensation'] = df['salary'] + df['annual_bonus']
# 3. 使用 assign 方法(返回新DataFrame)
df_new = df.assign(
tax = df['salary'] * 0.2,
net_salary = df['salary'] * 0.8
)
2.3 处理缺失值 #
# 创建有缺失值的示例数据
df_with_nan = pd.DataFrame({
'A': [1, 2, np.nan, 4, 5],
'B': [np.nan, 2, 3, np.nan, 5],
'C': [1, 2, 3, 4, 5]
})
# 1. 检测缺失值
missing_values = df_with_nan.isnull()
missing_count = df_with_nan.isnull().sum()
# 2. 填充缺失值
filled_df = df_with_nan.fillna(0) # 用0填充
filled_mean = df_with_nan.fillna(df_with_nan.mean()) # 用列均值填充
# 3. 删除缺失值
dropped_any = df_with_nan.dropna() # 删除任何包含NaN的行
dropped_all = df_with_nan.dropna(how='all') # 只删除全部为NaN的行
3. 高级查询技巧 #
3.1 使用 query 方法 #
# 1. 基本查询
result = df.query('age > 30 and salary > 60000')
# 2. 使用变量
min_age = 30
max_salary = 80000
result = df.query('age > @min_age and salary < @max_salary')
# 3. 复杂条件
result = df.query('(department == "IT" and age < 40) or (department == "HR" and salary > 65000)')
3.2 使用 eval 进行高效计算 #
# 对于大型DataFrame,eval可以更高效
df = pd.DataFrame(np.random.randn(10000, 4), columns=['A', 'B', 'C', 'D'])
# 传统方式
result1 = df[(df.A < 0.5) & (df.B > 0.5)]
# 使用eval(更高效)
result2 = df.eval('A < 0.5 and B > 0.5')
3.3 多层条件筛选 #
# 创建多层索引示例
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df_multi = pd.DataFrame(np.random.randn(8, 4), index=index, columns=['A', 'B', 'C', 'D'])
# 多层索引查询
result = df_multi.xs('bar', level='first') # 获取first级别为'bar'的所有行
result = df_multi.xs(('bar', 'one'), level=['first', 'second']) # 获取特定组合
4. 数据分组与聚合 #
4.1 基本分组操作 #
# 1. 按部门分组
grouped = df.groupby('department')
# 2. 获取分组统计
department_stats = grouped.agg({
'salary': ['mean', 'min', 'max', 'std'],
'age': 'mean'
})
# 3. 对每个分组应用函数
def top_earner(group):
return group.nlargest(1, 'salary')
top_earners_by_dept = grouped.apply(top_earner)
4.2 分组后更新数据 #
# 计算每个部门的平均工资
dept_avg_salary = df.groupby('department')['salary'].transform('mean')
# 添加新列显示与部门平均工资的差异
df['salary_diff_from_dept'] = df['salary'] - dept_avg_salary
# 为每个部门内的员工按工资排序
df['dept_salary_rank'] = df.groupby('department')['salary'].rank(ascending=False)
5. 处理日期数据 #
# 创建日期示例数据
date_rng = pd.date_range(start='2023-01-01', end='2023-01-10', freq='D')
df_dates = pd.DataFrame(date_rng, columns=['date'])
df_dates['value'] = np.random.randint(1, 100, size=(len(date_rng)))
# 1. 设置日期索引
df_dates.set_index('date', inplace=True)
# 2. 按时间范围筛选
jan_first_week = df_dates['2023-01-01':'2023-01-07']
# 3. 重采样(例如按周计算平均值)
weekly_avg = df_dates.resample('W').mean()
# 4. 提取日期部分
df_dates['year'] = df_dates.index.year
df_dates['month'] = df_dates.index.month
df_dates['day'] = df_dates.index.day
6. 性能优化技巧 #
6.1 使用合适的数据类型 #
# 查看当前数据类型
print(df.dtypes)
# 优化数据类型以减少内存使用
df['department'] = df['department'].astype('category')
df['city'] = df['city'].astype('category')
# 对于整数列,使用最小位数的整数类型
df['age'] = df['age'].astype('int8')
6.2 使用向量化操作 #
# 避免使用循环,使用向量化操作
# 慢的方式
def calculate_bonus(row):
if row['department'] == 'IT':
return row['salary'] * 0.15
else:
return row['salary'] * 0.10
# 快的方式(向量化)
df['bonus'] = np.where(df['department'] == 'IT', df['salary'] * 0.15, df['salary'] * 0.10)
7. 实用小技巧 #
7.1 随机抽样 #
# 随机抽取3行
sample = df.sample(n=3)
# 按比例抽样(20%)
sample_frac = df.sample(frac=0.2)
# 分层抽样(按部门)
stratified = df.groupby('department').apply(lambda x: x.sample(frac=0.3))
7.2 处理重复值 #
# 检测重复行
duplicates = df.duplicated()
# 删除完全重复的行
df_no_duplicates = df.drop_duplicates()
# 基于特定列删除重复行
df_no_duplicates_name = df.drop_duplicates(subset=['name'])
# 保留第一次出现或最后一次出现
df_keep_first = df.drop_duplicates(subset=['name'], keep='first')
df_keep_last = df.drop_duplicates(subset=['name'], keep='last')
这些操作涵盖了 Pandas 在数据筛选、查询和更新方面的常见用法。掌握这些技巧将大大提高数据处理的效率和能力。