选择数据
获取列
单列获取
要获取 DataFrame 的单个列,你可以使用列名以两种不同的方式:
- 使用点( .)操作符,这种方式更像是访问对象的属性。
- 使用方括号( [])和列名,这种方式更像是从字典中获取值。
假设我们有以下 DataFrame:
import pandas as pd
data = {
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [25, 30, 35],
'Salary': [50000, 70000, 80000]
}
df = pd.DataFrame(data)
获取 "Name" 列:
# 使用点操作符
name_column_dot = df.Name
# 使用方括号
name_column_brackets = df['Name']
多列获取
要获取 DataFrame 的多个列,你需要使用方括号( [])将列名的列表传递给它。这将返回一个新的 DataFrame,只包含指定的列。
获取 "Name" 和 "Age" 列:
columns = df[['Name', 'Age']]
列的条件选择
你可以使用条件表达式来选择满足特定条件的列。这通常结合使用布尔索引完成。
选择 "Salary" 大于 60000 的所有记录:
high_salary = df[df['Salary'] > 60000]
动态选择列
当你需要根据变量或计算结果来选择列时,可以使用 .loc[] 和 .iloc[] 方法。 .loc[] 用于基于列名选择,而 .iloc[] 用于基于列的整数位置选择。
# 使用 .loc[] 选择 'Name' 和 'Age' 列
selected_columns_loc = df.loc[:, ['Name', 'Age']]
# 使用 .iloc[] 选择前两列
selected_columns_iloc = df.iloc[:, 0:2]
获取行
使用.loc[](基于标签)
.loc[] 方法允许你通过标签索引来选择数据。当你知道行的标签名时,可以使用此方法。
import pandas as pd
data = {
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [25, 30, 35],
'Salary': [50000, 70000, 80000]
}
df = pd.DataFrame(data, index=['a', 'b', 'c'])
# 选择标签为 'a' 的行
row_a = df.loc['a']
# 选择标签为 'a' 和 'b' 的行
rows_ab = df.loc[['a', 'b']]
使用.iloc[](基于位置)
.iloc[] 方法允许你通过行的位置(整数索引)来选择数据。这是在你知道行的具体位置时的选择方法。
# 选择第一行
first_row = df.iloc[0]
# 选择前两行
first_two_rows = df.iloc[0:2]
使用条件表达式
你可以使用条件表达式来选择满足特定条件的行。这通常是通过将条件表达式放在方括号内完成的。
# 选择 Age 大于 30 的所有行
older_than_30 = df[df['Age'] > 30]
使用切片
对于连续的行,你还可以使用 Python 的切片语法来选择行。这种方法既可以用在 .loc[] 也可以用在 .iloc[] 中。
# 使用切片选择前两行
first_two_rows_slice = df[0:2]
使用.at[]和.iat[]获取单个值
当你需要访问 DataFrame 的单个元素时, .at[](基于标签)和 .iat[](基于整数位置)方法提供了更快的访问方式。
# 使用 .at[] 获取特定单元格的值
name_of_a = df.at['a', 'Name']
# 使用 .iat[] 获取特定单元格的值
first_name = df.iat[0, 0]
修改数据
在 Pandas 中,赋值操作是数据处理的核心部分,它允许你在 DataFrame 或 Series 中修改、添加或更新数据。Pandas 提供了灵活的赋值方法,适用于各种数据操作需求。这里将详细介绍如何在 Pandas 中进行赋值。
修改单个值
使用.at[]和.iat[]
- .at[] 用于根据行标签和列标签修改单个值。
- .iat[] 用于根据行和列的位置(整数索引)修改单个值。
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
# 使用行标签和列标签
df.at[0, 'A'] = 10
# 使用行和列的位置
df.iat[0, 1] = 40
修改多个值
使用布尔索引
布尔索引允许你根据条件来修改符合条件的多个值。
df[df['A'] > 1] = -1
使用.loc[]和.iloc[]
- .loc[] 根据行标签和列标签选择数据进行修改。
- .iloc[] 根据行和列的位置选择数据进行修改。
# 修改第一行的 'A' 列
df.loc[0, 'A'] = 20
# 修改前两行的 'B' 列
df.loc[:1, 'B'] = [50, 60]
# 使用 .iloc 修改第一行第一列
df.iloc[0, 0] = 30
添加或更新列
直接赋值
直接赋值是添加新列或修改现有列最直接的方法。
# 添加新列 'C'
df['C'] = [7, 8, 9]
# 修改列 'A'
df['A'] = [100, 200, 300]
使用.assign()方法
.assign() 方法可以一次添加多个新列,返回修改后的新 DataFrame,原 DataFrame 不变。
df = df.assign(D=[10, 11, 12], E=[13, 14, 15])
使用条件赋值
可以结合条件表达式和 np.where 方法来根据条件赋值。
import numpy as np
# 'A' 列大于 100 的设置 'F' 列为 'High',否则为 'Low'
df['F'] = np.where(df['A'] > 100, 'High', 'Low')
使用.apply()和.map()方法
这些方法允许对 DataFrame 或 Series 的数据应用函数,并根据函数返回值进行赋值。
# 使用.apply()按行或列应用函数
df['G'] = df['A'].apply(lambda x: x * 2)
# 使用.map()对Series的每个元素应用一个函数或值的映射
df['H'] = df['F'].map({'High': 1, 'Low': 0})
运算
基本算术运算
Pandas 允许直接对数据结构进行加、减、乘、除等基本算术运算。这些操作可以是两个 Series 或 DataFrame 之间的运算,也可以是 Series 或 DataFrame 与单一数值之间的运算。
与单一数值的运算
import pandas as pd
import numpy as np
# 创建 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
})
# 加法
df_add = df + 10
# 减法
df_sub = df - 10
# 乘法
df_mul = df * 10
# 除法
df_div = df / 10
两个DataFrame或Series之间的运算
df1 = pd.DataFrame(np.arange(9).reshape(3, 3), columns=['A', 'B', 'C'])
df2 = pd.DataFrame(np.ones((3, 3)), columns=['A', 'B', 'C'])
# 加法
df_add = df1 + df2
# 减法
df_sub = df1 - df2
# 乘法
df_mul = df1 * df2
# 除法
df_div = df1 / df2
广播机制
Pandas 在执行算术运算时支持广播机制。当对 DataFrame 和 Series 进行运算时, Series 的索引会与 DataFrame 的列对齐,然后沿着行向下广播。
series = pd.Series([1, 2, 3], index=['A', 'B', 'C'])
# 与 DataFrame 进行运算
df_add = df + series
使用函数进行运算
Pandas 提供了一些函数来执行特定的算术运算,如 .add(), .sub(), .mul(), .div() 等,这些函数提供了更灵活的运算方式,如填充值(用于处理缺失数据)。
# 使用函数执行加法,并指定填充值
df_add = df1.add(df2, fill_value=0)
累计运算
Pandas 提供了累计运算方法,如 .cumsum() 累计求和, .cumprod() 累计乘积等。
# 累计求和
cum_sum = df.cumsum()
# 累计乘积
cum_prod = df.cumprod()
统计
描述性统计
常用的描述性统计方法
- count():计算非空值的数量。
- mean():计算数值型列的平均值。
- median():计算数值型列的中位数。
- min():计算数值型列的最小值。
- max():计算数值型列的最大值。
- std():计算数值型列的标准差。
- var():计算数值型列的方差。
- sum():计算数值型列的总和。
- quantile(q=0.5):计算数值型列的分位数, q 范围是 0 到 1。
- describe():生成数值型列的描述性统计摘要。
import pandas as pd
import numpy as np
# 创建一个示例 DataFrame
df = pd.DataFrame({
'A': [1, 2, np.nan, 4, 5],
'B': [7, 8, 9, 10, 11],
'C': ['a', 'b', 'c', 'd', 'e']
})
# 描述性统计
print(df.describe())
# 平均值
print(df.mean())
# 中位数
print(df.median())
累计统计函数
Pandas 还提供了累计统计的方法,如累计和( cumsum)、累计积( cumprod)、累计最大值( cummax)和累计最小值( cummin)。
# 累计和
print(df['B'].cumsum())
# 累计积
print(df['B'].cumprod())
# 累计最大值
print(df['B'].cummax())
# 累计最小值
print(df['B'].cummin())
相关性和协方差
分析数值变量之间的关系时,相关系数和协方差是两个重要的统计量。
- corr():计算列之间的相关系数矩阵。
- cov():计算列之间的协方差矩阵。
# 计算相关系数矩阵
print(df.corr())
# 计算协方差矩阵
print(df.cov())
其他统计方法
- value_counts():计算一个 Series 或 DataFrame 某列中各值出现的频次,常用于分类数据。
- unique():获取 Series 中的唯一值数组。
- nunique():获取 Series 中唯一值的数量。
# value_counts 示例
print(df['C'].value_counts())
# unique 示例
print(df['C'].unique())
# nunique 示例
print(df['C'].nunique())
## 处理缺失数据
- 删除含有缺失值的行或列: df.dropna()
- 填充缺失值: df.fillna(value)
排序
按索引排序
使用 sort_index() 方法可以按索引排序。这适用于 Series 和 DataFrame 对象。对于 DataFrame,你可以分别按行索引或列索引排序。
Series按索引排序
import pandas as pd
s = pd.Series([3, 1, 4, 1, 5], index=['e', 'd', 'a', 'b', 'c'])
sorted_s = s.sort_index()
DataFrame按行索引排序
df = pd.DataFrame({
'A': [5, 3, 1, 2, 4],
'B': [10, 0, 30, 20, 40]
}, index=['e', 'd', 'a', 'b', 'c'])
sorted_df = df.sort_index()
DataFrame按列索引排序
sorted_df = df.sort_index(axis=1)
按值排序
使用 sort_values() 方法可以根据一列或多列的值对 DataFrame 或 Series 进行排序。
Series按值排序
sorted_s = s.sort_values()
DataFrame按单列值排序
# 按列 'A' 的值排序
sorted_df = df.sort_values(by='A')
DataFrame按多列值排序
# 先按列 'A' 排序,列 'A' 值相同的情况下按列 'B' 排序
sorted_df = df.sort_values(by=['A', 'B'])
升序和降序排序
sort_values() 和 sort_index() 方法都接受 ascending 参数,用于控制排序是按升序还是降序进行。默认为升序( ascending=True)。
# 按列 'A' 的值降序排序
sorted_df = df.sort_values(by='A', ascending=False)
# 按索引降序排序
sorted_df = df.sort_index(ascending=False)
处理缺失值
在排序时,Pandas 默认将缺失值( NaN)排序到最后。你可以通过 na_position 参数控制缺失值的位置。
# 缺失值排在前面
sorted_df = df.sort_values(by='A', na_position='first')
实例:排序和查看
对于数据探索和分析,排序是一个常见步骤,用于快速检查数据的最高值、最低值或发现潜在的异常值。
# 查看 'A' 列的最高5个值
print(df.sort_values(by='A', ascending=False).head(5))
# 查看 'B' 列的最低5个值
print(df.sort_values(by='B').head(5))
处理缺失值
Pandas 提供了强大的工具来处理缺失数据,这对于数据清洗和准备阶段是非常重要的。在 Pandas 中,缺失值一般用 NaN (Not a Number) 来表示,但对于时间序列数据,也可能用 NaT (Not a Time) 表示。处理这些缺失值是数据分析不可或缺的一部分,以下是 Pandas 处理缺失值的详细教程。
检测缺失值
isna()和notna()
Pandas 提供了 isna() 和 notna() 方法来检测数据中的缺失值。这两个方法可以应用于 Series 和 DataFrame。
import pandas as pd
import numpy as np
# 创建示例 DataFrame
df = pd.DataFrame({
'A': [1, np.nan, 3],
'B': [4, 5, np.nan],
'C': [np.nan, np.nan, np.nan]
})
# 检测缺失值
print(df.isna())
# 检测非缺失值
print(df.notna())
处理缺失值
删除缺失值
dropna()
使用 dropna() 方法可以删除包含缺失值的行或列。通过 axis 参数,你可以选择删除包含缺失值的行 ( axis=0 或 axis='index') 或列 ( axis=1 或 axis='columns')。
# 删除任何包含缺失值的行
df_dropna_rows = df.dropna()
# 删除任何包含缺失值的列
df_dropna_cols = df.dropna(axis='columns')
# 删除所有值都是缺失值的行
df_drop_all_na = df.dropna(how='all')
填充缺失值
fillna()
fillna() 方法提供了多种方式来填充缺失值,包括使用固定值、前一个或后一个值填充,或使用某种计算得出的值填充。
# 使用固定值填充缺失值
df_filled = df.fillna(0)
# 使用前一个值填充缺失值
df_fill_forward = df.fillna(method='ffill')
# 使用后一个值填充缺失值
df_fill_backward = df.fillna(method='bfill')
替换缺失值
除了使用 fillna(),你还可以使用 replace() 方法替换数据框中的特定值,包括 NaN。
# 替换所有 NaN 值为 0
df_replaced = df.replace(np.nan, 0)
使用interpolate()插值
interpolate() 方法提供了一种方法来填充缺失值,该方法可以在缺失值之间进行线性插值。
# 线性插值填充缺失值
df_interpolated = df.interpolate()
使用drop_duplicates()删除重复行
虽然不直接与处理缺失值相关,但删除重复行是数据清洗过程中的一个重要步骤。
# 删除重复行
df_no_duplicates = df.drop_duplicates()
数据合并
使用concat进行拼接
concat 函数可以沿着一条轴将多个对象堆叠到一起。适用于简单地合并多个 DataFrame 或 Series,不考虑索引和列名的对齐。
基本语法
pd.concat(objs, axis=0, join='outer', ignore_index=False)
- objs:一个列表或字典,里面包含要被合并的 DataFrame 或 Series 对象。
- axis:默认为 0,表示沿着行方向进行合并;如果设为 1,则沿着列方向进行合并。
- join:默认为 'outer',表示执行外连接;如果设为 'inner',则执行内连接。
- ignore_index:如果为 True,则不使用索引值,创建一个新的 range(total_length) 索引。
import pandas as pd
df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})
result = pd.concat([df1, df2])
使用merge进行合并
merge 函数用于通过一个或多个键将行连接起来。类似于 SQL 中的 JOIN 操作。
基本语法
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None)
- left、 right:要合并的左、右 DataFrame 或 Series 对象。
- how:指定如何合并。默认为 'inner',还可以是 'outer'、'left'、'right'。
- on:用于连接的列名。必须在左右 DataFrame 中都存在。
- left_on、 right_on:左、右 DataFrame 中用作连接键的列名,可以是列名或列名的列表。
left = pd.DataFrame({'key': ['K0', 'K1'], 'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
right = pd.DataFrame({'key': ['K0', 'K1'], 'C': ['C0', 'C1'], 'D': ['D0', 'D1']})
result = pd.merge(left, right, on='key')
使用join进行连接
join 函数用于将两个 DataFrame 按照索引进行合并,可以是列与索引之间的合并。
基本语法
DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='')
- other:另一个 DataFrame 或要加入的 Series 或多个 DataFrame。
- on:指定用于连接的列。
- how:指定如何合并。默认为 'left',还可以是 'right'、'outer'、'inner'。
- lsuffix、 rsuffix:在列名冲突时使用的后缀。
left = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']}, index=['K0', 'K1'])
right = pd.DataFrame({'C': ['C0', 'C1'], 'D': ['D0', 'D1']}, index=['K0', 'K1'])
result = left.join(right)
分组
分组操作是数据分析中的一个强大工具,允许你对数据集进行分割、应用函数和组合结果。这种 "split-apply-combine" 策略非常适用于聚合、转换和过滤数据。以下是 Pandas 分组的详细教程,涵盖 groupby 函数的使用。
使用groupby进行分组
groupby 方法基于某些标准将数据分成多个组,然后可以对每个组应用聚合函数,最后将结果组合到一个数据结构中。
基本语法
df.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False)
- by:分组依据,可以是列名、列名的列表或其他序列。
- axis:默认为 0,表示沿行的方向进行分组。
- level:如果轴是多层索引(MultiIndex),则根据级别分组。
- as_index:默认为 True,返回的对象以组标签作为索引。
- sort:默认为 True,根据组键对结果进行排序。
import pandas as pd
# 创建示例 DataFrame
df = pd.DataFrame({
'Company': ['Google', 'Google', 'Microsoft', 'Microsoft', 'Facebook', 'Facebook'],
'Employee': ['Sam', 'Charlie', 'Amy', 'Vanessa', 'Carl', 'Sarah'],
'Sales': [200, 120, 340, 124, 243, 350]
})
# 按公司分组并计算每个公司的平均销售额
grouped = df.groupby('Company')
avg_sales = grouped['Sales'].mean()
聚合函数
分组后,你可以对每个组应用聚合函数来计算统计信息,如 sum、 mean、 max、 min 等。
示例
# 计算每个公司的最高销售额
max_sales = grouped['Sales'].max()
# 同时应用多个聚合函数
agg_sales = grouped['Sales'].agg(['mean', 'sum', 'max', 'min'])
转换和过滤
除了聚合,分组还可以进行转换( transform)和过滤( filter)操作。
转换
转换操作会返回与原始数据相同长度的对象。
# 标准化每个公司的销售数据
standardized_sales = grouped['Sales'].transform(lambda x: (x - x.mean()) / x.std())
过滤
过滤操作允许你根据布尔条件删除或保留某些组。
# 过滤出平均销售额大于 250 的公司
filtered_companies = grouped.filter(lambda x: x['Sales'].mean() > 250)
groupby对象的属性和方法
groupby 对象提供了一系列有用的属性和方法,如 groups 属性,可以查看分组情况。
# 查看分组情况
print(grouped.groups)
多层分组
可以根据多个列进行分组,实现多层分组。
# 假设我们有另一列 "Year"
df['Year'] = [2019, 2019, 2020, 2020, 2019, 2020]
# 根据公司和年份进行分组
grouped_multi = df.groupby(['Company', 'Year'])
multi_avg_sales = grouped_multi['Sales'].mean()
输入输出
Pandas 提供了一系列功能强大的工具来读取和写入多种格式的数据,包括 CSV、Excel、JSON、HTML 和 SQL 数据库等。
读取数据
读取 CSV 文件
import pandas as pd
# 默认情况下,假设第一行是列名
df = pd.read_csv('filename.csv')
# 如果 CSV 文件没有列名
df = pd.read_csv('filename.csv', header=None)
# 指定列名
df = pd.read_csv('filename.csv', names=['column1', 'column2', 'column3'])
# 指定索引列
df = pd.read_csv('filename.csv', index_col='column1')
读取 Excel 文件
# 读取第一个工作簿
df = pd.read_excel('filename.xlsx', sheet_name=0)
# 通过工作簿名称读取
df = pd.read_excel('filename.xlsx', sheet_name='Sheet1')
读取 JSON 文件
df = pd.read_json('filename.json')
从 SQL 数据库读取
Pandas 可以与 SQLAlchemy 或 SQLite3 等库配合使用,从 SQL 数据库中读取数据。
from sqlalchemy import create_engine
# 创建数据库引擎
engine = create_engine('sqlite:///filename.db')
# 读取表格
df = pd.read_sql('tablename', con=engine)
写入数据
写入 CSV 文件
df.to_csv('filename.csv', index=False)
写入 Excel 文件
df.to_excel('filename.xlsx', sheet_name='Sheet1')
写入 JSON 文件
df.to_json('filename.json')
写入到 SQL 数据库
df.to_sql('tablename', con=engine, if_exists='replace', index=False)
参数和配置
Pandas 的读取和写入函数提供了大量的参数来配置数据的输入输出操作。以下是一些常用参数:
- sep 或 delimiter: 指定字段的分隔符,用于 read_csv 和 to_csv。
- header: 指定作为列名的行的索引。
- index_col: 用作行索引的列编号或列名。
- names: 列名列表,用于结果的列。
- sheet_name: 用于 read_excel 和 to_excel,指定 Excel 工作簿的名称或索引。
- if_exists: 写入 SQL 时,如果表格已存在,是替换、追加还是报错。
- index: 写入文件时,是否将索引写入。
- encoding: 指定字符集类型,如 utf-8。