0%

pandas基础使用教程

pandas基础使用教程

在数据分析领域,pandas是Python生态中最强大、最常用的库之一。它提供了高效的数据结构和数据分析工具,使得数据处理、清洗、分析和可视化变得简单易用。本文将详细介绍pandas的基础使用方法,包括依赖库、基本概念、数据操作、常见错误及解决方案等内容。

一、依赖的库

要使用pandas进行数据分析,我们需要安装一些必要的依赖库。

1. pandas

pandas是核心库,提供了DataFrame和Series等数据结构,以及各种数据操作功能。

安装方法

1
pip install pandas

版本要求

  • 推荐使用最新稳定版本
  • 目前稳定版本:v2.2.4(截至2026年1月)

2. numpy

numpy是pandas的基础依赖,提供了高效的数值计算功能。

安装方法

1
pip install numpy

版本要求

  • 推荐版本:v2.1.0或更高

3. matplotlib(可选)

matplotlib用于数据可视化,pandas内置了对matplotlib的支持。

安装方法

1
pip install matplotlib

版本要求

  • 推荐版本:v3.9.0或更高

4. seaborn(可选)

seaborn是基于matplotlib的高级可视化库,提供了更美观的图表样式。

安装方法

1
pip install seaborn

版本要求

  • 推荐版本:v0.13.2或更高

二、基本概念

pandas有两个核心数据结构:Series和DataFrame。

1. Series

Series是一维带标签的数组,类似于带索引的列表。

创建Series

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pandas as pd
import numpy as np

# 从列表创建
ser1 = pd.Series([1, 2, 3, 4, 5])
print("从列表创建的Series:")
print(ser1)
print()

# 从字典创建
ser2 = pd.Series({'a': 1, 'b': 2, 'c': 3})
print("从字典创建的Series:")
print(ser2)
print()

# 带自定义索引
ser3 = pd.Series([1, 2, 3], index=['x', 'y', 'z'])
print("带自定义索引的Series:")
print(ser3)

2. DataFrame

DataFrame是二维带标签的数据结构,类似于电子表格或SQL表。

创建DataFrame

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 从字典创建
df1 = pd.DataFrame({
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [25, 30, 35],
'City': ['New York', 'London', 'Paris']
})
print("从字典创建的DataFrame:")
print(df1)
print()

# 从列表创建
data = [
['Alice', 25, 'New York'],
['Bob', 30, 'London'],
['Charlie', 35, 'Paris']
]
df2 = pd.DataFrame(data, columns=['Name', 'Age', 'City'])
print("从列表创建的DataFrame:")
print(df2)
print()

# 从numpy数组创建
data = np.random.randint(0, 100, size=(5, 3))
df3 = pd.DataFrame(data, columns=['A', 'B', 'C'])
print("从numpy数组创建的DataFrame:")
print(df3)

三、数据读取与写入

pandas支持多种文件格式的数据读取和写入。

1. CSV文件

读取CSV文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 读取本地CSV文件
df = pd.read_csv('data.csv')

# 读取网络CSV文件
df = pd.read_csv('https://example.com/data.csv')

# 读取时指定参数
df = pd.read_csv(
'data.csv',
sep=',', # 分隔符
header=0, # 表头行
index_col=0, # 索引列
na_values=['NA'], # 缺失值标记
encoding='utf-8' # 编码
)

写入CSV文件

1
2
3
4
5
6
7
8
9
10
11
# 写入CSV文件
df.to_csv('output.csv')

# 写入时指定参数
df.to_csv(
'output.csv',
index=False, # 不写入索引
header=True, # 写入表头
sep=',', # 分隔符
encoding='utf-8' # 编码
)

2. Excel文件

读取Excel文件

1
2
3
4
5
6
7
8
# 读取Excel文件
df = pd.read_excel('data.xlsx')

# 读取指定工作表
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')

# 读取多个工作表
dfs = pd.read_excel('data.xlsx', sheet_name=['Sheet1', 'Sheet2'])

写入Excel文件

1
2
3
4
5
6
7
8
9
10
# 写入Excel文件
df.to_excel('output.xlsx')

# 写入指定工作表
df.to_excel('output.xlsx', sheet_name='Sheet1')

# 写入多个工作表
with pd.ExcelWriter('output.xlsx') as writer:
df1.to_excel(writer, sheet_name='Sheet1')
df2.to_excel(writer, sheet_name='Sheet2')

3. JSON文件

读取JSON文件

1
2
3
4
5
# 读取JSON文件
df = pd.read_json('data.json')

# 读取嵌套JSON
df = pd.read_json('nested.json', orient='records')

写入JSON文件

1
2
3
4
5
# 写入JSON文件
df.to_json('output.json')

# 写入时指定格式
df.to_json('output.json', orient='records', indent=2)

四、数据清洗与预处理

数据清洗是数据分析的重要步骤,包括处理缺失值、重复值、异常值等。

1. 处理缺失值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 查看缺失值情况
print(df.isnull().sum())

# 删除包含缺失值的行
df_clean = df.dropna()

# 删除包含缺失值的列
df_clean = df.dropna(axis=1)

# 填充缺失值
df_filled = df.fillna(0) # 用0填充
print(df_filled)

df_filled = df.fillna({'Age': 30, 'City': 'Unknown'}) # 按列填充
print(df_filled)

df_filled = df.fillna(method='ffill') # 向前填充
print(df_filled)

df_filled = df.fillna(method='bfill') # 向后填充
print(df_filled)

df_filled = df.fillna(df.mean()) # 用均值填充
print(df_filled)

2. 处理重复值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看重复值
print(df.duplicated())

# 查看重复值数量
print(df.duplicated().sum())

# 删除重复值
df_unique = df.drop_duplicates()
print(df_unique)

# 按指定列删除重复值
df_unique = df.drop_duplicates(subset=['Name'])
print(df_unique)

# 保留最后一个重复值
df_unique = df.drop_duplicates(keep='last')
print(df_unique)

3. 数据类型转换

1
2
3
4
5
6
7
8
9
10
11
12
# 查看数据类型
print(df.dtypes)

# 转换数据类型
df['Age'] = df['Age'].astype(int) # 转换为整数
print(df.dtypes)

df['Date'] = pd.to_datetime(df['Date']) # 转换为日期时间
print(df.dtypes)

df['Price'] = pd.to_numeric(df['Price']) # 转换为数值型
print(df.dtypes)

4. 数据标准化与归一化

1
2
3
4
5
6
7
8
9
10
11
# 标准化(z-score)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df['Age_scaled'] = scaler.fit_transform(df[['Age']])
print(df)

# 归一化(min-max)
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
df['Age_normalized'] = scaler.fit_transform(df[['Age']])
print(df)

五、数据筛选与查询

1. 基本筛选

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 选择列
df['Name'] # 选择单列
print(df['Name'])

df[['Name', 'Age']] # 选择多列
print(df[['Name', 'Age']])

# 行索引选择
df.loc[0] # 按标签选择行
print(df.loc[0])

df.loc[0:2] # 按标签切片
print(df.loc[0:2])

df.iloc[0] # 按位置选择行
print(df.iloc[0])

df.iloc[0:2] # 按位置切片
print(df.iloc[0:2])

# 条件筛选
df[df['Age'] > 30] # 年龄大于30的行
print(df[df['Age'] > 30])

df[(df['Age'] > 30) & (df['City'] == 'New York')] # 多条件筛选
print(df[(df['Age'] > 30) & (df['City'] == 'New York')])

df[df['City'].isin(['New York', 'London'])] # 包含于列表
print(df[df['City'].isin(['New York', 'London'])])

2. 高级查询

1
2
3
4
5
6
7
8
9
10
# 使用query方法
df.query('Age > 30')
print(df.query('Age > 30'))

df.query('Age > 30 and City == "New York"')
print(df.query('Age > 30 and City == "New York"'))

# 使用eval方法计算新列
df.eval('Age_in_months = Age * 12')
print(df.eval('Age_in_months = Age * 12'))

六、数据分组与聚合

1. 数据分组

1
2
3
4
5
6
7
8
9
10
11
12
13
# 按单列分组
grouped = df.groupby('City')
print(grouped)

# 按多列分组
grouped = df.groupby(['City', 'Gender'])
print(grouped)

# 分组后查看每组数据
for name, group in grouped:
print(f"Group: {name}")
print(group)
print()

2. 聚合操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 常用聚合函数
print(grouped['Age'].count()) # 计数
print(grouped['Age'].sum()) # 求和
print(grouped['Age'].mean()) # 均值
print(grouped['Age'].median()) # 中位数
print(grouped['Age'].std()) # 标准差
print(grouped['Age'].min()) # 最小值
print(grouped['Age'].max()) # 最大值

# 多聚合函数
grouped['Age'].agg(['count', 'sum', 'mean', 'min', 'max'])
print(grouped['Age'].agg(['count', 'sum', 'mean', 'min', 'max']))

# 不同列使用不同聚合函数
grouped.agg({
'Age': ['mean', 'std'],
'Salary': ['sum', 'max']
})

3. 分组转换

1
2
3
4
5
6
7
8
# 计算每组的均值并广播到原数据
print(grouped['Age'].transform('mean'))

# 使用自定义函数
def normalize(x):
return (x - x.mean()) / x.std()

print(grouped['Age'].transform(normalize))

4. 分组过滤

1
2
# 过滤掉年龄均值小于30的组
print(grouped.filter(lambda x: x['Age'].mean() > 30))

七、数据可视化

pandas内置了对matplotlib的支持,可以直接绘制各种图表。

1. 基本图表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import matplotlib.pyplot as plt

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号

# 折线图
df.plot(kind='line', x='Date', y='Value')
plt.title('折线图')
plt.show()

# 柱状图
df.plot(kind='bar', x='Name', y='Age')
plt.title('柱状图')
plt.show()

# 直方图
df['Age'].plot(kind='hist', bins=10)
plt.title('直方图')
plt.show()

# 散点图
df.plot(kind='scatter', x='Age', y='Salary')
plt.title('散点图')
plt.show()

# 箱线图
df.plot(kind='box', y=['Age', 'Salary'])
plt.title('箱线图')
plt.show()

# 饼图
df['City'].value_counts().plot(kind='pie', autopct='%1.1f%%')
plt.title('饼图')
plt.axis('equal')
plt.show()

2. 使用seaborn可视化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import seaborn as sns

# 热力图
corr = df.corr()
sns.heatmap(corr, annot=True, cmap='coolwarm')
plt.title('热力图')
plt.show()

# 成对关系图
sns.pairplot(df[['Age', 'Salary', 'Experience']])
plt.title('成对关系图')
plt.show()

# 分类柱状图
sns.barplot(x='City', y='Salary', data=df)
plt.title('分类柱状图')
plt.show()

# 小提琴图
sns.violinplot(x='City', y='Age', data=df)
plt.title('小提琴图')
plt.show()

八、完整代码示例

下面是一个完整的pandas基础使用示例,展示了从数据读取到分析的整个流程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 1. 创建示例数据
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank', 'Grace', 'Henry', 'Ivy', 'Jack'],
'Age': [25, 30, 35, 40, 45, 50, 55, 60, 65, 70],
'City': ['New York', 'London', 'Paris', 'Tokyo', 'Sydney', 'New York', 'London', 'Paris', 'Tokyo', 'Sydney'],
'Salary': [50000, 60000, 70000, 80000, 90000, 100000, 110000, 120000, 130000, 140000],
'Experience': [2, 5, 8, 11, 14, 17, 20, 23, 26, 29]
}

df = pd.DataFrame(data)
print("原始数据:")
print(df)
print()

# 2. 数据基本信息
print("数据基本信息:")
print(df.info())
print()

print("数据统计描述:")
print(df.describe())
print()

# 3. 数据清洗
# 假设添加一些缺失值
import copy
df_with_na = copy.deepcopy(df)
df_with_na.loc[2, 'Age'] = np.nan
df_with_na.loc[5, 'Salary'] = np.nan

print("包含缺失值的数据:")
print(df_with_na)
print()

print("缺失值情况:")
print(df_with_na.isnull().sum())
print()

# 处理缺失值
df_clean = df_with_na.fillna({
'Age': df_with_na['Age'].mean(),
'Salary': df_with_na['Salary'].median()
})

print("处理缺失值后的数据:")
print(df_clean)
print()

# 4. 数据筛选与查询
print("年龄大于50岁的数据:")
print(df_clean[df_clean['Age'] > 50])
print()

print("来自New York且薪资大于80000的数据:")
print(df_clean[(df_clean['City'] == 'New York') & (df_clean['Salary'] > 80000)])
print()

# 5. 数据分组与聚合
print("按城市分组的平均年龄和薪资:")
grouped = df_clean.groupby('City')
print(grouped[['Age', 'Salary']].mean())
print()

# 6. 数据可视化
# 薪资与经验的关系
df_clean.plot(kind='scatter', x='Experience', y='Salary', color='blue', marker='o', s=50)
plt.title('薪资与工作经验的关系')
plt.xlabel('工作经验(年)')
plt.ylabel('薪资(美元)')
plt.grid(True)
plt.show()

# 不同城市的薪资分布
sns.barplot(x='City', y='Salary', data=df_clean, palette='viridis')
plt.title('不同城市的平均薪资')
plt.xlabel('城市')
plt.ylabel('平均薪资(美元)')
plt.xticks(rotation=45)
plt.show()

# 年龄分布直方图
df_clean['Age'].plot(kind='hist', bins=5, color='green', alpha=0.7)
plt.title('年龄分布')
plt.xlabel('年龄')
plt.ylabel('人数')
plt.grid(True, alpha=0.3)
plt.show()

# 7. 导出结果
df_clean.to_csv('cleaned_data.csv', index=False)
print("数据已导出到cleaned_data.csv")

九、常见错误及解决方案

1. 缺失值处理错误

错误信息ValueError: Input contains NaN, infinity or a value too large for dtype('float64')

解决方案

  • 在进行数值计算前,先处理缺失值
  • 使用df.dropna()删除缺失值
  • 使用df.fillna()填充缺失值
  • 检查数据中是否有无穷大值,使用df.replace([np.inf, -np.inf], np.nan)处理

2. 数据类型不匹配

错误信息TypeError: unsupported operand type(s) for +: 'int' and 'str'

解决方案

  • 检查数据类型,使用df.dtypes查看
  • 转换数据类型,使用df.astype()pd.to_numeric()
  • 确保进行运算的列具有兼容的数据类型

3. 索引错误

错误信息KeyError: 'column_name'

解决方案

  • 检查列名是否正确,注意大小写
  • 使用df.columns查看所有列名
  • 确保列名没有空格或特殊字符
  • 使用df.rename(columns={'old_name': 'new_name'})重命名列

错误信息IndexError: single positional indexer is out-of-bounds

解决方案

  • 检查索引范围,使用df.shape查看数据形状
  • 确保索引值在有效范围内
  • 使用.loc[].iloc[]进行安全索引

4. 内存不足

错误信息MemoryError

解决方案

  • 读取大数据时使用chunksize参数分块读取
  • 选择性读取需要的列,使用usecols参数
  • 转换数据类型为更节省内存的类型,如int8float16
  • 使用df.memory_usage()查看内存使用情况

5. 文件路径错误

错误信息FileNotFoundError: [Errno 2] No such file or directory: 'data.csv'

解决方案

  • 检查文件路径是否正确
  • 确认文件存在
  • 使用绝对路径代替相对路径
  • 检查文件权限

十、进阶用法

1. 时间序列处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 创建时间序列索引
date_rng = pd.date_range(start='2026-01-01', end='2026-01-31', freq='D')
df = pd.DataFrame(date_rng, columns=['date'])
df['value'] = np.random.randint(0, 100, size=(len(date_rng)))
df.set_index('date', inplace=True)

# 时间序列重采样
df.resample('W').mean() # 按周重采样
df.resample('M').sum() # 按月重采样

# 移动窗口计算
df['rolling_mean'] = df['value'].rolling(window=7).mean() # 7天移动平均
df['rolling_std'] = df['value'].rolling(window=7).std() # 7天移动标准差

# 差分运算
df['diff'] = df['value'].diff() # 一阶差分

2. 多索引操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建多索引
df = pd.DataFrame({
'year': [2024, 2024, 2025, 2025],
'quarter': [1, 2, 1, 2],
'sales': [100, 200, 300, 400]
})

df_multi = df.set_index(['year', 'quarter'])
print(df_multi)

# 多索引查询
df_multi.loc[(2024, 1)] # 查询特定索引
df_multi.xs(2024, level='year') # 按年份查询
df_multi.xs(1, level='quarter') # 按季度查询

# 重置索引
df_flat = df_multi.reset_index()
print(df_flat)

3. 合并与连接数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 创建示例数据
df1 = pd.DataFrame({
'id': [1, 2, 3, 4],
'name': ['Alice', 'Bob', 'Charlie', 'David'],
'city': ['New York', 'London', 'Paris', 'Tokyo']
})

df2 = pd.DataFrame({
'id': [2, 3, 4, 5],
'salary': [50000, 60000, 70000, 80000],
'experience': [2, 5, 8, 11]
})

# 内连接
df_inner = pd.merge(df1, df2, on='id', how='inner')
print(df_inner)

# 左连接
df_left = pd.merge(df1, df2, on='id', how='left')
print(df_left)

# 右连接
df_right = pd.merge(df1, df2, on='id', how='right')
print(df_right)

# 外连接
df_outer = pd.merge(df1, df2, on='id', how='outer')
print(df_outer)

# 追加数据
df_append = df1.append(df2, ignore_index=True)
print(df_append)

# 拼接数据
df_concat = pd.concat([df1, df2], axis=1)
print(df_concat)

4. 高性能操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 使用向量化操作代替循环
df['new_col'] = df['col1'] + df['col2'] # 向量化操作,高效

# 使用apply与自定义函数
df['new_col'] = df.apply(lambda row: row['col1'] + row['col2'], axis=1) # 比循环高效,但比向量化操作慢

# 使用numba加速
from numba import njit

@njit
def calculate(x, y):
return x + y

df['new_col'] = calculate(df['col1'].values, df['col2'].values) # 高效

# 使用Dask处理大数据
dask_df = dd.from_pandas(df, npartitions=4)
result = dask_df.groupby('city')['salary'].mean().compute()

十一、总结

本文详细介绍了pandas的基础使用方法,包括:

  1. 依赖库:pandas、numpy、matplotlib、seaborn等
  2. 基本概念:Series和DataFrame数据结构
  3. 数据读取与写入:支持CSV、Excel、JSON等多种格式
  4. 数据清洗与预处理:处理缺失值、重复值、数据类型转换等
  5. 数据筛选与查询:基本筛选、条件查询、高级查询
  6. 数据分组与聚合:分组、聚合、转换、过滤
  7. 数据可视化:基本图表、seaborn可视化
  8. 完整代码示例:从数据创建到可视化的完整流程
  9. 常见错误及解决方案:缺失值处理、数据类型不匹配、索引错误等
  10. 进阶用法:时间序列处理、多索引操作、合并与连接数据、高性能操作

pandas是数据分析的强大工具,掌握其基础使用方法对于数据分析工作至关重要。通过本文的学习,你应该能够使用pandas进行基本的数据处理、分析和可视化。

在实际应用中,建议结合具体需求,深入学习pandas的高级功能,如时间序列分析、数据透视表、高性能计算等。同时,多实践、多总结,不断提高自己的数据分析能力。

十二、参考资料

  1. pandas官方文档
  2. numpy官方文档
  3. matplotlib官方文档
  4. seaborn官方文档
  5. Python数据分析实战
  6. pandas cookbook
  7. Data Science Handbook
  8. pandas中文教程

欢迎关注我的其它发布渠道