“`python
–– coding: utf-8 ––
“””
使用 Pandas 进行数据分析 (Python)
“””
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
一、 Pandas 简介
Pandas 是 Python 中一个强大的数据分析库,它提供了高效的数据结构,例如 DataFrame 和 Series,以及用于数据清洗、转换、分析和可视化的各种工具。Pandas 建立在 NumPy 库之上,并与其无缝集成,使得数据操作变得更加简单快捷。
1.1 Pandas 的优势
- 高效的数据结构: DataFrame 和 Series 是 Pandas 的核心数据结构,它们可以高效地存储和处理表格型数据和一维数据。
- 数据清洗和转换: Pandas 提供了丰富的功能来处理缺失值、重复值、异常值,并进行数据类型转换、数据排序、数据过滤等操作。
- 数据分析: Pandas 提供了强大的数据聚合、分组、透视表等功能,方便进行统计分析、探索性数据分析 (EDA)。
- 数据可视化: Pandas 可以与 Matplotlib 和 Seaborn 等可视化库集成,轻松创建各种图表,例如折线图、柱状图、散点图、箱线图等。
- 数据导入和导出: Pandas 支持从各种数据源导入数据,例如 CSV、Excel、SQL 数据库、JSON 等,并可以将数据导出到这些格式。
1.2 Pandas 的安装
可以使用 pip 包管理器来安装 Pandas:
bash
pip install pandas
1.3 Pandas 的基本数据结构:Series 和 DataFrame
-
Series: Series 是一种带标签的一维数组,可以存储任何数据类型(整数、浮点数、字符串、Python 对象等)。标签被称为索引,用于访问 Series 中的元素。
-
DataFrame: DataFrame 是一种带标签的二维表格型数据结构,可以看作是 Series 的集合。DataFrame 具有行索引和列索引,类似于 Excel 表格或 SQL 表。
二、Pandas 的基本操作
2.1 创建 Series
“`python
从列表创建 Series
data = [10, 20, 30, 40, 50]
s = pd.Series(data)
print(s)
指定索引
s = pd.Series(data, index=[‘a’, ‘b’, ‘c’, ‘d’, ‘e’])
print(s)
从 NumPy 数组创建 Series
data = np.array([1, 2, 3, 4, 5])
s = pd.Series(data)
print(s)
从字典创建 Series
data = {‘a’: 1, ‘b’: 2, ‘c’: 3, ‘d’: 4, ‘e’: 5}
s = pd.Series(data)
print(s)
“`
2.2 创建 DataFrame
“`python
从字典创建 DataFrame
data = {‘Name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’],
‘Age’: [25, 30, 28, 22],
‘City’: [‘New York’, ‘London’, ‘Paris’, ‘Tokyo’]}
df = pd.DataFrame(data)
print(df)
从列表的列表创建 DataFrame
data = [[‘Alice’, 25, ‘New York’],
[‘Bob’, 30, ‘London’],
[‘Charlie’, 28, ‘Paris’],
[‘David’, 22, ‘Tokyo’]]
df = pd.DataFrame(data, columns=[‘Name’, ‘Age’, ‘City’])
print(df)
从 NumPy 数组创建 DataFrame
data = np.array([[‘Alice’, 25, ‘New York’],
[‘Bob’, 30, ‘London’],
[‘Charlie’, 28, ‘Paris’],
[‘David’, 22, ‘Tokyo’]])
df = pd.DataFrame(data, columns=[‘Name’, ‘Age’, ‘City’])
print(df)
“`
2.3 数据导入和导出
“`python
从 CSV 文件导入数据
df = pd.read_csv(‘data.csv’)
从 Excel 文件导入数据
df = pd.read_excel(‘data.xlsx’)
从 SQL 数据库导入数据
import sqlite3
conn = sqlite3.connect(‘data.db’)
df = pd.read_sql_query(“SELECT * FROM table_name”, conn)
conn.close()
导出到 CSV 文件
df.to_csv(‘data_output.csv’, index=False) # index=False 避免导出索引列
导出到 Excel 文件
df.to_excel(‘data_output.xlsx’, index=False)
导出到 SQL 数据库
import sqlite3
conn = sqlite3.connect(‘data_output.db’)
df.to_sql(‘table_name’, conn, if_exists=’replace’, index=False) # if_exists 控制如何处理已存在的表,’replace’是替换, ‘append’是追加
conn.close()
“`
2.4 数据访问和选择
“`python
选择列
print(df[‘Name’]) # 选择 ‘Name’ 列
print(df[[‘Name’, ‘Age’]]) # 选择 ‘Name’ 和 ‘Age’ 列
选择行
print(df.loc[0]) # 选择第一行 (索引为 0)
print(df.loc[0:2]) # 选择前三行 (索引为 0, 1, 2)
print(df.iloc[0]) # 使用整数索引选择第一行
print(df.iloc[0:3]) #使用整数索引选择前三行
使用条件选择行
print(df[df[‘Age’] > 25]) # 选择 ‘Age’ 大于 25 的行
print(df[(df[‘Age’] > 25) & (df[‘City’] == ‘London’)]) # 选择 ‘Age’ 大于 25 且 ‘City’ 为 ‘London’ 的行
使用 loc 和 iloc 进行更灵活的选择
print(df.loc[df[‘Age’] > 25, [‘Name’, ‘City’]]) # 选择 ‘Age’ 大于 25 的行的 ‘Name’ 和 ‘City’ 列
print(df.iloc[0:2, 0:2]) # 选择前两行,前两列
“`
2.5 数据清洗
“`python
处理缺失值
print(df.isnull().sum()) # 检查每列的缺失值数量
df.dropna() # 删除包含缺失值的行
df.fillna(0) # 用 0 填充缺失值
df[‘Age’].fillna(df[‘Age’].mean(), inplace=True) # 用 ‘Age’ 列的平均值填充缺失值
处理重复值
print(df.duplicated().sum()) # 检查重复行的数量
df.drop_duplicates(inplace=True) # 删除重复行
数据类型转换
df[‘Age’] = df[‘Age’].astype(int) # 将 ‘Age’ 列转换为整数类型
df[‘City’] = df[‘City’].astype(‘category’) # 将 ‘City’ 列转换为 category 类型
删除列
df.drop(‘City’, axis=1, inplace=True) # 删除 ‘City’ 列 (axis=1 表示列)
重命名列
df.rename(columns={‘Name’: ‘FullName’}, inplace=True)
替换数据
df[‘FullName’].replace(‘Alice’, ‘Alicia’, inplace=True)
字符串操作
df[‘FullName’] = df[‘FullName’].str.upper() #将 ‘FullName’列转换为大写
df[‘FullName’] = df[‘FullName’].str.lower() #将 ‘FullName’列转换为小写
df[‘FullName’] = df[‘FullName’].str.strip() #去除 ‘FullName’列字符串首尾的空格
“`
2.6 数据转换
“`python
添加新列
df[‘Salary’] = [50000, 60000, 55000, 48000] # 添加 ‘Salary’ 列
基于现有列计算新列
df[‘Salary_Increase’] = df[‘Salary’] * 0.1 # 计算 ‘Salary’ 的 10% 增长
使用 apply 函数进行更复杂的转换
def categorize_salary(salary):
if salary > 55000:
return ‘High’
elif salary > 50000:
return ‘Medium’
else:
return ‘Low’
df[‘Salary_Category’] = df[‘Salary’].apply(categorize_salary)
使用 lambda 函数进行简单转换
df[‘Age_Plus_One’] = df[‘Age’].apply(lambda x: x + 1)
Apply 函数可以作用于行或列
def row_summary(row):
return f”{row[‘FullName’]} is {row[‘Age’]} years old and earns {row[‘Salary’]}”
df[‘Summary’] = df.apply(row_summary, axis=1)
“`
2.7 数据分析
“`python
统计描述
print(df.describe()) # 生成数值列的统计描述,包括均值、标准差、最小值、最大值等
计算均值、中位数、标准差等
print(df[‘Age’].mean())
print(df[‘Age’].median())
print(df[‘Age’].std())
计算相关性
print(df.corr()) # 计算数值列之间的相关性
计数
print(df[‘Salary_Category’].value_counts()) # 统计 Salary_Category 列中每个值的出现次数
分组
grouped = df.groupby(‘Salary_Category’)
print(grouped[‘Age’].mean()) # 计算每个 Salary_Category 的平均年龄
print(grouped.agg({‘Age’: ‘mean’, ‘Salary’: ‘sum’})) #对Age计算均值,对Salary计算总和
透视表
pivot_table = pd.pivot_table(df, values=’Salary’, index=’City’, columns=’Salary_Category’, aggfunc=’mean’)
print(pivot_table)
“`
2.8 数据可视化
“`python
折线图
df[‘Age’].plot()
plt.xlabel(‘Index’)
plt.ylabel(‘Age’)
plt.title(‘Age Distribution’)
plt.show()
柱状图
df[‘Salary_Category’].value_counts().plot(kind=’bar’)
plt.xlabel(‘Salary Category’)
plt.ylabel(‘Count’)
plt.title(‘Salary Category Distribution’)
plt.show()
散点图
plt.scatter(df[‘Age’], df[‘Salary’])
plt.xlabel(‘Age’)
plt.ylabel(‘Salary’)
plt.title(‘Age vs. Salary’)
plt.show()
箱线图
df.boxplot(column=’Salary’, by=’Salary_Category’)
plt.xlabel(‘Salary Category’)
plt.ylabel(‘Salary’)
plt.title(‘Salary Distribution by Category’)
plt.show()
直方图
df[‘Age’].hist()
plt.xlabel(‘Age’)
plt.ylabel(‘Frequency’)
plt.title(‘Age Histogram’)
plt.show()
“`
三、高级 Pandas 操作
3.1 多重索引
DataFrame 可以具有多重索引 (MultiIndex),允许对数据进行更复杂的层次化分组和分析。
“`python
创建多重索引 DataFrame
data = {‘Region’: [‘North’, ‘North’, ‘South’, ‘South’, ‘East’, ‘East’],
‘Year’: [2020, 2021, 2020, 2021, 2020, 2021],
‘Sales’: [100, 120, 150, 180, 80, 90]}
df = pd.DataFrame(data)
df = df.set_index([‘Region’, ‘Year’])
print(df)
访问多重索引 DataFrame
print(df.loc[(‘North’, 2020)]) # 访问 ‘North’ 地区 2020 年的数据
print(df.loc[(‘North’, 2020), ‘Sales’]) #访问具体数值
使用 xs 函数进行跨层级选择
print(df.xs(‘North’, level=’Region’)) #选择所有Region为North的数据
对多重索引进行排序
df = df.sort_index()
“`
3.2 数据合并和连接
Pandas 提供了 merge
、join
和 concat
函数来合并和连接 DataFrame。
-
merge
: 基于列的值进行连接,类似于 SQL 中的 JOIN 操作。 -
join
: 基于索引进行连接。 -
concat
: 沿着轴 (行或列) 连接 DataFrame。
“`python
创建两个 DataFrame
df1 = pd.DataFrame({‘ID’: [1, 2, 3, 4],
‘Name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’]})
df2 = pd.DataFrame({‘ID’: [1, 2, 5, 6],
‘Salary’: [50000, 60000, 70000, 80000]})
使用 merge 连接 DataFrame
merged_df = pd.merge(df1, df2, on=’ID’, how=’inner’) # 内连接,只保留两个 DataFrame 中都存在的 ID
print(merged_df)
其他连接方式:left, right, outer
merged_df_left = pd.merge(df1, df2, on=’ID’, how=’left’) #左连接,保留df1的所有行
merged_df_right = pd.merge(df1, df2, on=’ID’, how=’right’) #右连接,保留df2的所有行
merged_df_outer = pd.merge(df1, df2, on=’ID’, how=’outer’) #外连接,保留所有行,缺失值用NaN填充
使用join连接DataFrame
df1 = df1.set_index(‘ID’)
df2 = df2.set_index(‘ID’)
joined_df = df1.join(df2, how=’inner’)
使用 concat 连接 DataFrame
df3 = pd.DataFrame({‘Age’: [25, 30, 28, 22]})
concatenated_df = pd.concat([df1, df3], axis=1) # 沿着列连接
print(concatenated_df)
“`
3.3 时间序列分析
Pandas 提供了强大的时间序列分析功能。
“`python
创建时间序列
dates = pd.date_range(‘2023-01-01′, periods=100, freq=’D’)
ts = pd.Series(np.random.randn(len(dates)), index=dates)
print(ts)
重采样
ts_monthly = ts.resample(‘M’).mean() # 将数据按月重采样,计算平均值
print(ts_monthly)
滑动窗口
ts_rolling = ts.rolling(window=7).mean() # 计算 7 天的滑动平均值
print(ts_rolling)
时间序列分解(需要安装statsmodels)
from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(ts, model=’additive’, period=30)
decomposition.plot()
plt.show()
“`
四、总结
Pandas 是 Python 中进行数据分析的必备库。它提供了高效的数据结构和丰富的功能,使得数据清洗、转换、分析和可视化变得更加简单快捷。 通过掌握 Pandas 的基本操作和高级技巧,可以更好地处理和分析数据,从而提取有价值的信息。 本文介绍了 Pandas 的基本概念、常用操作和高级技巧,希望能帮助读者更好地入门和使用 Pandas 进行数据分析。 为了更深入地了解Pandas, 建议阅读官方文档以及参考其他优秀的教程和书籍。实践是最好的老师,多做练习才能真正掌握 Pandas 的使用。
“`