Python Pandas Dataframe核心操作详解
1. DataFrame 基础操作
1.1 创建 DataFrame
1.1.1 通过字典创建
import pandas as pd
# 通过字典创建
data_dict = {
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'gender': ['Female', 'Male', 'Male']
}
df = pd.DataFrame(data_dict)
print(df)
输出:
name age gender
0 Alice 25 Female
1 Bob 30 Male
2 Charlie 35 Male
1.1.2 通过列表创建
# 通过列表创建
data_list = [['Alice', 25, 'Female'], ['Bob', 30, 'Male']]
df = pd.DataFrame(data_list, columns=['name', 'age', 'gender'])
print(df)
输出:
name age gender
0 Alice 25 Female
1 Bob 30 Male
1.1.3 通过二维数组创建
import numpy as np
# 通过二维数组创建
data_array = np.array([[25, 'Female'], [30, 'Male']])
df = pd.DataFrame(data_array, columns=['age', 'gender'])
print(df)
输出:
age gender
0 25 Female
1 30 Male
1.2 查看数据
1.2.1 head()
和 tail()
print(df.head(2)) # 显示前2行
print(df.tail(1)) # 显示后1行
输出:
name age gender
0 Alice 25 Female
1 Bob 30 Male
name age gender
2 Charlie 35 Male
1.2.2 shape
print(df.shape) # 输出:(3, 3)
1.2.3 columns
print(df.columns) # 输出:Index(['name', 'age', 'gender'], dtype='object')
1.2.4 dtypes
print(df.dtypes)
输出:
name object
age int64
gender object
dtype: object
1.3 数据统计与描述
1.3.1 describe()
print(df.describe())
输出:
age
count 3.0
mean 30.0
std 5.0
min 25.0
25% 27.5
50% 30.0
75% 32.5
max 35.0
1.3.2 info()
print(df.info())
输出:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 name 3 non-null object
1 age 3 non-null int64
2 gender 3 non-null object
dtypes: int64(1), object(2)
memory usage: 192.0+ bytes
None
2. 数据筛选与过滤
2.1 基于列名筛选
# 选择单列
selected_column = df['age']
print(selected_column)
# 选择多列
selected_columns = df[['name', 'gender']]
print(selected_columns)
输出:
0 25
1 30
2 35
Name: age, dtype: int64
name gender
0 Alice Female
1 Bob Male
2 Charlie Male
2.2 基于行索引筛选
# 通过行索引
row = df.iloc[0] # 第0行
print(row)
# 通过布尔索引
filtered_df = df[df['age'] > 30]
print(filtered_df)
输出:
name Alice
age 25
gender Female
Name: 0, dtype: object
name age gender
2 Charlie 35 Male
2.3 复合条件筛选
# 筛选年龄>30且性别为Male的行
filtered_df = df[(df['age'] > 30) & (df['gender'] == 'Male')]
print(filtered_df)
输出:
name age gender
2 Charlie 35 Male
3. 数据清洗与处理
3.1 处理缺失值
3.1.1 isnull()
和 notnull()
print(df.isnull()) # 返回布尔型DataFrame
print(df.notnull())
3.1.2 dropna()
# 删除包含任一缺失值的行
cleaned_df = df.dropna(axis=0, how='any')
# 删除所有值均为缺失值的列
cleaned_df = df.dropna(axis=1, how='all')
3.1.3 fillna()
# 用均值填充数值列
df['age'].fillna(df['age'].mean(), inplace=True)
# 用前向填充(pad)或后向填充(bfill)
df.fillna(method='ffill', inplace=True) # 前向填充
3.2 数据去重
3.2.1 duplicated()
print(df.duplicated()) # 返回布尔型Series
3.2.2 drop_duplicates()
unique_df = df.drop_duplicates()
3.3 数据排序
# 按年龄升序排序
sorted_df = df.sort_values(by='age', ascending=True)
# 按年龄降序排序
sorted_df = df.sort_values(by='age', ascending=False)
4. 数据转换与重置
4.1 reset_index()
# 重置索引并删除原索引列
df.reset_index(drop=True, inplace=True)
4.2 set_index()
# 将"name"列设为索引
df.set_index('name', inplace=True)
4.3 astype()
# 将年龄列转换为浮点型
df['age'] = df['age'].astype(float)
5. 数据合并与连接
5.1 concat()
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
# 按行拼接(axis=0)
concat_df = pd.concat([df1, df2], axis=0)
# 按列拼接(axis=1)
concat_df = pd.concat([df1, df2], axis=1)
输出:
按行拼接:
A B
0 1 3
1 2 4
0 5 7
1 6 8
按列拼接:
A B A B
0 1 3 5 7
1 2 4 6 8
5.2 merge()
# 左连接(left join)
left_df = pd.DataFrame({'key': ['K0', 'K1', 'K2'], 'A': ['A0', 'A1', 'A2']})
right_df = pd.DataFrame({'key': ['K0', 'K1', 'K3'], 'B': ['B0', 'B1', 'B3']})
merged_df = pd.merge(left_df, right_df, on='key', how='left')
print(merged_df)
输出:
key A B
0 K0 A0 B0
1 K1 A1 B1
2 K2 A2 NaN
6. 数据分组与聚合
6.1 groupby()
# 按性别分组,计算平均年龄
grouped = df.groupby('gender')['age'].mean()
print(grouped)
输出:
gender
Female 25.0
Male 32.5
Name: age, dtype: float64
6.2 pivot_table()
# 创建透视表,按性别分组,计算年龄的均值和总和
pivot_table = df.pivot_table(values='age', index='gender', aggfunc=['mean', 'sum'])
print(pivot_table)
输出:
mean sum
gender
Female 25.0 25
Male 32.5 65
7. 数据导出与导入
7.1 导出到文件
# 导出为CSV
df.to_csv('output.csv', index=False)
# 导出为Excel
df.to_excel('output.xlsx', sheet_name='Sheet1', index=False)
7.2 从Excel导入数据
# 读取Excel文件
df = pd.read_excel('input.xlsx', sheet_name='Sheet1')
# 读取特定列
df = pd.read_excel('input.xlsx', usecols=['name', 'age'])
8. 高级操作
8.1 apply()
# 计算年龄的平方
def square(x):
return x ** 2
df['age_squared'] = df['age'].apply(square)
print(df)
输出:
name age gender age_squared
0 Alice 25 Female 625
1 Bob 30 Male 900
2 Charlie 35 Male 1225
8.2 处理时间序列
# 创建时间序列索引
df['date'] = pd.date_range(start='2023-01-01', periods=3)
df.set_index('date', inplace=True)
# 按周聚合
weekly_df = df.resample('W').mean()
9. Excel 集成与注意事项
9.1 在 Excel 中使用 Python DataFrame
示例代码:
# 在 Excel 中输出为值
import pandas as pd
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
print(df) # Excel 中会直接填充到单元格
9.2 使用 Power Query 导入数据
# 通过 Power Query 导入数据到 Excel 后,使用 Python 处理
df = pd.read_excel('imported_data.xlsx')
processed_df = df[df['age'] > 30]
processed_df.to_excel('output.xlsx')
10. 常见问题与解决方案
10.1 处理重复索引
# 重置索引并删除原索引列
df = df.reset_index(drop=True)
10.2 合并时列名冲突
# 使用 suffixes 参数避免列名冲突
merged_df = pd.merge(left_df, right_df, on='key', how='left', suffixes=('_left', '_right'))
10.3 处理大文件
# 分块读取大文件
for chunk in pd.read_csv('large_file.csv', chunksize=1000):
process(chunk)
11. 实际应用案例
11.1 数据清洗全流程
# 读取数据
df = pd.read_csv('data.csv')
# 处理缺失值
df.fillna({'age': 0, 'gender': 'Unknown'}, inplace=True)
# 删除重复行
df.drop_duplicates(inplace=True)
# 转换数据类型
df['age'] = df['age'].astype(int)
# 保存清洗后的数据
df.to_csv('cleaned_data.csv', index=False)
11.2 分析用户行为数据
# 计算不同性别的平均消费
grouped = df.groupby('gender')['purchase_amount'].mean()
# 创建透视表
pivot_table = df.pivot_table(index='country', columns='product', values='sales', aggfunc='sum')
12. 数据可视化
12.1 使用 Matplotlib
import matplotlib.pyplot as plt
# 绘制年龄分布直方图
plt.figure(figsize=(10, 6))
df['age'].plot(kind='hist', bins=5, edgecolor='black')
plt.title('Age Distribution')
plt.xlabel('Age')
plt.ylabel('Count')
plt.show()
12.2 使用 Seaborn
import seaborn as sns
# 绘制性别与年龄的箱线图
plt.figure(figsize=(10, 6))
sns.boxplot(x='gender', y='age', data=df)
plt.title('Age by Gender')
plt.show()
13. 数据类型转换
13.1 转换为字典
# 转换为字典(按列)
dict_data = df.to_dict(orient='list')
print(dict_data)
输出:
{'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 35], 'gender': ['Female', 'Male', 'Male']}
13.2 转换为 NumPy 数组
# 转换为 NumPy 数组
numpy_array = df.values
print(numpy_array)
输出:
[['Alice' 25 'Female']
['Bob' 30 'Male']
['Charlie' 35 'Male']]
14. 其他实用方法
14.1 sample()
随机采样
# 随机采样50%的数据
sampled_df = df.sample(frac=0.5)
14.2 nunique()
统计唯一值
# 统计性别列的唯一值数量
unique_count = df['gender'].nunique()
print(unique_count) # 输出:2
14.3 replace()
替换值
# 将年龄中的25替换为26
df['age'] = df['age'].replace(25, 26)
15. 性能优化技巧
15.1 使用 apply
的优化
# 向量化操作代替 apply
df['age_squared'] = df['age'] ** 2 # 比 apply 更高效
15.2 使用 eval()
和 query()
# 使用 eval() 进行快速计算
df['age_squared'] = df.eval('age ** 2')
# 使用 query() 进行条件筛选
filtered_df = df.query('age > 30')
16. 数据库交互
16.1 从 SQL 数据库读取数据
from sqlalchemy import create_engine
# 创建数据库连接
engine = create_engine('mysql+pymysql://username:password@host:port/database')
# 读取 SQL 表
df = pd.read_sql_query('SELECT * FROM table_name', con=engine)
16.2 将数据写入数据库
# 写入 SQL 表
df.to_sql('table_name', con=engine, if_exists='replace', index=False)
17. 特殊操作示例
17.1 处理分层索引(MultiIndex)
# 创建多级索引
df = df.set_index(['gender', 'age'])
print(df)
输出:
name
gender age
Female 25 Alice
Male 30 Bob
Male 35 Charlie
17.2 使用 melt()
转换数据格式
# 将宽格式转为长格式
melted_df = df.melt(id_vars=['name'], value_vars=['age'], var_name='metric', value_name='value')
print(melted_df)
输出:
name metric value
0 Alice age 25
1 Bob age 30
2 Charlie age 35
18. 错误处理与调试
18.1 处理 KeyError
try:
print(df['invalid_column'])
except KeyError:
print("列不存在!")
18.2 处理 ValueError
try:
df['age'] = df['age'].astype(str)
except ValueError:
print("无法转换为字符串类型!")
19. 高级数据操作
19.1 使用 assign()
添加新列
# 添加新列并计算年龄的平方根
df = df.assign(age_sqrt=lambda x: np.sqrt(x['age']))
19.2 使用 groupby
的高级聚合
# 自定义聚合函数
def custom_agg(x):
return x.max() - x.min()
grouped = df.groupby('gender')['age'].agg(['mean', custom_agg])
作者:y2016724