Pandas基础
Pandas 是一个强大的 Python 数据分析工具包,非常适合用于处理和分析输入数据,常用于数据清洗和准备。它建立在 NumPy 的基础上,让数据预处理、清洗、分析工作变得更快更简单。Pandas 引入了两个主要的数据结构:Series 和 DataFrame。
Series
Series 是一个一维标记数组,能够保存任何数据类型(整数、字符串、浮点数、Python 对象等)。轴标签统称为索引。
import pandas as pd
# 创建 Series
s = pd.Series([1, 3, 5, np.nan, 6, 8])
# 显示 Seriesprint(s)
DataFrame
DataFrame 是一个二维标记数据结构,可以将其想象为一个电子表格或 SQL 表,或一个 Series 对象的字典。它通常是使用 CSV 文件、SQL 数据库或其他数据源创建的。
# 使用字典创建 DataFrame
df = pd.DataFrame({
'A': 1.,
'B': pd.Timestamp('20230101'),
'C': pd.Series(1, index=list(range(4)), dtype='float32'),
'D': np.array([3] * 4, dtype='int32'),
'E': pd.Categorical(["test", "train", "test", "train"]),
'F': 'foo'
})
# 显示 DataFrameprint(df)
查看数据
# 查看 DataFrame 头部数据
print(df.head())
# 查看 DataFrame 尾部数据
print(df.tail(3))
# 显示索引、列和底层 NumPy 数据
print(df.index)
print(df.columns)
print(df.values)
# 描述显示数据的快速统计概述print(df.describe())
# 数据转置print(df.T)
选择一个单独的列
这将返回一个 Series,等同于 df.A。
print(df['A'])
通过 [] 进行选择,这将切片行
print(df[0:3])
print(df['20230102':'20230104'])
使用标签选择数据
# 获取特定的标签值
print(df.loc[:, ['A', 'B']])
# 标签切片
print(df.loc['20230102':'20230104', ['A', 'B']])
# 获取特定标签的标量值
print(df.loc['20230101', 'A'])
# 快速访问一个标量(与上一个方法等价)
print(df.at['20230101', 'A'])
使用位置选择数据
print(df.iloc[3])
# 通过整数切片
print(df.iloc[3:5, 0:2])
# 通过整数位置的列表
print(df.iloc[[1, 2, 4], [0, 2]])
# 明确切片行print(df.iloc[1:3, :])
# 明确切片列print(df.iloc[:, 1:3])
# 获取特定值print(df.iloc[1, 1])
# 快速访问标量(与上一个方法等价)print(df.iat[1, 1])
布尔索引
# 使用单个列的值选择数据
print(df[df['A'] > 0])
# 使用 where 操作选择数据
print(df[df > 0])
# 使用 isin() 方法进行筛选
df2 = df.copy()
df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three']
print(df2[df2['E'].isin(['two', 'four'])])
设置数据
# 设置新列自动对齐数据索引
s1 = pd.Series([1, 2, 3, 4, 5, 6], index=pd.date_range('20230102', periods=6))
df['F'] = s1
# 按标签设置值
df.at['20230101', 'A'] = 0# 按位置设置值
df.iat[0, 1] = 0# 使用 NumPy 数组设置一组新值
df.loc[:, 'D'] = np.array([5] * len(df))
# 带有 where 条件的设置操作
df2 = df.copy()
df2[df2 > 0] = -df2
缺失数据
Pandas 主要使用 np.nan 来表示缺失数据。计算时,默认不包括空值。
# 重建索引(reindex)可以改变/添加/删除指定轴的索引,并返回数据的副本
df1 = df.reindex(index=df.index[0:4], columns=list(df.columns) + ['E'])
df1.loc[df.index[0]:df.index[1], 'E'] = 1print(df1)
# 删除所有含有缺失数据的行print(df1.dropna(how='any'))
# 填充缺失数据print(df1.fillna(value=5))
数据输入输出
Pandas 支持多种数据源的读写操作。
# CSV
df.to_csv('my_dataframe.csv')
pd.read_csv('my_dataframe.csv')
# Excel
df.to_excel('my_dataframe.xlsx', sheet_name='Sheet1')
pd.read_excel('my_dataframe.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
Pandas的series
在Python的数据分析库pandas中,Series是一个非常基础也是非常重要的数据结构。我们来逐步详细讲解它。
- Series是什么?
在pandas中,Series可以被看作是一维的数组结构,与NumPy中的一维ndarray相似,但它除了可以存储数据以外,还可以为数据索引附上标签。Series可以存储任何类型的数据,如整数、浮点数、字符串、Python对象等。 - Series的创建
Series可以通过多种方式创建,最简单的是从列表创建。
import pandas as pd
# 从列表创建Series
data = [1, 2, 3, 4]
series = pd.Series(data)
print(series)
当你创建一个Series时,如果不指定索引,pandas会默认提供一个从0开始的数值索引。你也可以指定索引:
# 指定索引
series_with_index = pd.Series(data, index=['a', 'b', 'c', 'd'])
print(series_with_index)
此外,你还可以从字典、NumPy数组等创建Series。
3.Series的索引
在Series中,索引是数据的关键。你可以通过索引的方式选取单个元素,也可以选取一组元素。
# 通过索引获取元素
print(series_with_index['a'])
# 切片访问
print(series_with_index['a':'c'])
- Series的操作
你可以对Series进行各种操作,比如数学运算、统计分析等。
# 数学运算
print(series + 100)
# 统计分析
print(series.mean())
- Series的向量化操作
与NumPy数组类似,Series支持向量化操作,这意味着你可以不用编写循环即可对数据进行批量处理。
# 向量化加法
new_series = series_with_index + series_with_index
print(new_series)
- Series的缺失数据处理
Series有一套自己的方法来处理缺失数据。
# 假设我们有缺失数据的Series
series_with_nan = pd.Series([1, None, 3, None, 5])
# 判断数据是否是缺失值print(series_with_nan.isnull())
# 填充缺失值print(series_with_nan.fillna(0))
- Series与DataFrame的关系
在pandas中,DataFrame是一个二维的表格型数据结构。你可以把DataFrame看作是多个Series的集合,即它的每一列都可以是一个Series。
# 创建一个DataFrame
df = pd.DataFrame({'column1': series, 'column2': series_with_index})
print(df)
- Series的转换
你可以将Series转换成其他类型的数据结构,比如列表或字典。
# Series转列表
list_from_series = series.tolist()
# Series转字典
dict_from_series = series_with_index.to_dict()
DataFrame
DataFrame是Pandas库中最常用的数据结构,也是大多数数据分析任务的中心。下面我将从多个角度详细解释DataFrame的概念和用法。
- DataFrame是什么?
DataFrame是一个二维大小可变的表格型数据结构,具有可变的列类型,你可以把它想象成一个Excel表格或者SQL表。每一列称为一个Series,可以包含任意类型的数据(整数、字符串、浮点数、Python对象等)。DataFrame既有行索引也有列索引,是一个非常强大的数据操作工具。 - DataFrame的创建
从字典创建DataFrame
最常见的方法是从一个字典创建:
import pandas as pd
# 字典的键将成为列名
data = {
'Column1': [1, 2, 3, 4],
'Column2': ['a', 'b', 'c', 'd']
}
df = pd.DataFrame(data)
print(df)
从列表创建DataFrame
你也可以从一个列表的列表创建DataFrame:
# 每个子列表将成为一行
data = [
[1, 'a'],
[2, 'b'],
[3, 'c'],
[4, 'd']
]
df = pd.DataFrame(data, columns=['Column1', 'Column2'])
print(df)
- 访问DataFrame的数据
通过列名访问数据
你可以通过列名来访问数据,这将返回一个Series:
print(df['Column1'])
通过行号访问数据
你可以使用.iloc通过行号访问数据:
# 返回第一行
print(df.iloc[0])
通过行标签访问数据
如果你的DataFrame有明确的行标签(index),你可以使用.loc通过行标签访问数据:
# 假设我们的DataFrame有行标签
df.index = ['Row1', 'Row2', 'Row3', 'Row4']
print(df.loc['Row1'])
- DataFrame的操作
DataFrame支持多种操作,包括但不限于:
- 数据选择与过滤
- 数据添加与删除
- 排序
- 分组
- 合并与连接
- 统计分析
- 数据转换
- 数据选择与过滤
选择列
# 选择单列
column1 = df['Column1']
# 选择多列
columns = df[['Column1', 'Column2']]
选择行
# 通过条件选择行
rows = df[df['Column1'] > 2]
- 添加与删除列
添加列
df['Column3'] = [5, 6, 7, 8]
删除列
df.drop('Column3', axis=1, inplace=True)
8. 分组
# 按某列的值进行分组
grouped = df.groupby('Column2')
9. 合并与连接
# 连接两个DataFrame
other_df = pd.DataFrame({'Column3': [5, 6, 7, 8]})
df_merged = pd.concat([df, other_df], axis=1)
10. 统计分析
# 描述性统计
df.describe()
# 求平均值
df.mean()
11. 数据转换
p
# 应用函数到列
df['Column1'] = df['Column1'].apply(lambda x: x * 10)
Pandas索引与数据选择
Pandas中的索引和数据选择是数据分析过程中最常用的操作之一。理解如何高效地选择所需的数据是进行数据分析的关键。以下是使用Pandas进行索引和数据选择的一些基本方法:
- 基于列的选择
选择DataFrame中的列非常直接。可以通过列名以字典方式进行选择。
import pandas as pd
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
})
# 选择单列
a = df['A']
# 选择多列
b_and_c = df[['B', 'C']]
- 基于行的选择
使用 loc 和 iloc
Pandas 提供了 loc 和 iloc 两个强大的方法,用于基于行和列的标签或位置进行选择。
- loc: 基于标签的索引,即使用列名或行标签来选择数据。
- iloc: 基于位置的索引,即使用列和行的整数位置(从0开始)来选择数据。
# 使用 loc 选择第一行数据
first_row = df.loc[0]
# 使用 loc 选择 A 列的所有行
a_column = df.loc[:, 'A']
# 使用 loc 同时选择特定的行和列
sub_data = df.loc[0:1, ['A', 'B']]
# 使用 iloc 选择第一行第一列的数据
first_item = df.iloc[0, 0]
# 使用 iloc 选择前两行的数据
first_two_rows = df.iloc[0:2]
- 条件选择
你可以使用条件表达式选择满足条件的数据。
# 选择 'A' 列中大于 1 的所有行
condition = df['A'] > 1
filtered_df = df[condition]
# 可以用更简洁的方式来写
filtered_df = df[df['A'] > 1]
# 多个条件可以结合使用 &(和), |(或)
filtered_df = df[(df['A'] > 1) & (df['B'] < 6)]
- at 和 iat 方法
如果你要选择一个单一的标量值,Pandas 提供了 at 和 iat 方法。它们分别对应 loc 和 iloc,但是专门用于快速访问单个值。
# 使用 at 获取特定的单一值
specific_value = df.at[0, 'A']
# 使用 iat 获取特定的单一值
specific_value = df.iat[0, 0]
- 切片
切片操作与Python列表类似,但在Pandas中更加强大。
# 选择前两行
first_two_rows = df[0:2]
# 使用切片与 loc 结合来选择行
first_two_rows = df.loc[0:1]
# 使用切片与 iloc 结合来选择行和列
subset = df.iloc[0:2, 0:2]
- 布尔索引
Pandas 允许使用布尔向量直接索引数据。这在处理复杂条件时特别有用。
# 创建一个布尔向量
bools = [True, False, True]
filtered_df = df[bools]
Pandas信息统计
Pandas 是一个专门用于数据分析和处理的强大Python库。它为数据统计提供了非常丰富的功能,能帮助我们快速了解数据集的特点、分布情况、相关性以及其他统计学信息。接下来,我们将详细讨论Pandas在数据统计方面的一些常用方法和应用。
基本统计方法
首先,我们讨论几个最基础的统计方法:
- 计数 (count): 返回非NA/NaN的值的数量。
- 求和 (sum): 返回数值类型列的和。
- 均值 (mean): 计算数值类型列的算术平均值。
- 中位数 (median): 计算数值类型列的中位数值。
- 众数 (mode): 返回数据中出现次数最多的值。
- 最小值 (min): 计算数值类型列的最小值。
- 最大值 (max): 计算数值类型列的最大值。
- 标准差 (std): 计算数值类型列的标准差。
- 方差 (var): 计算数值类型列的方差。
- 累积求和 (cumsum): 返回累积和。
- 累积最大值 (cummax): 返回累积最大值。
- 累积最小值 (cummin): 返回累积最小值。
- 累积乘积 (cumprod): 返回累积乘积。
- 乘机 (prod): 返回数值类型列的所有值的乘积。
import pandas as pd
import numpy as np
# 假设有以下DataFrame:
df = pd.DataFrame({
'A': [1, 2, 3, 4],
'B': [5, 6, np.nan, 8], # numpy.nan是一个特殊的浮点值
'C': [9, 10, 11, 12]
})
# 调用基本统计方法
print(df.count()) # 计数
print(df.sum()) # 求和
print(df.mean()) # 均值# ...以此类推
描述性统计
Pandas的 describe() 方法提供了数据列的多个统计汇总。默认情况下,它会返回数值列的计数、均值、标准差、最小值、25%、50%、75%分位数和最大值。
# 描述性统计
print(df.describe())
相关性分析
相关性分析是统计学中的一个重要部分,它可以帮助我们理解不同数值变量之间的线性关系。Pandas提供了 corr() 方法来计算列与列之间的相关系数,默认计算的是皮尔逊相关系数。
# 计算相关系数矩阵
print(df.corr())
数据排名
Pandas的 rank() 方法可以为每个元素在其所在列中的排名。默认情况下,rank() 为元素分配平均排名,但你可以修改方法来使用不同的排名策略,例如最小排名、最大排名等。
# 计算排名
print(df.rank())
唯一值、值计数和成员资格
- unique() 方法可以得到列中的唯一值数组。
- value_counts() 方法计算一个Series中各值出现的频率。
- isin() 方法可以用来过滤数据集,把参数中存在的值设为True,不存在的设为False。
# 唯一值
print(df['A'].unique())
# 值计数
print(df['B'].value_counts())
# 成员资格
print(df['A'].isin([1, 3]))
使用统计方法处理缺失数据
Pandas在计算统计时默认忽略缺失值。例如,求和或均值的计算将不包括NaN或None值。如果需要修改这种行为,可以使用参数来调整。
# 计算均值时忽略NaN
print(df.mean())
# 如果想要包括NaN,可以通过参数skipna=False来修改
print(df.mean(skipna=False))
求和 (Sum)
total = df['A'].sum()
Pandas应用函数
当你在处理pandas DataFrame时,你会遇到许多情况,需要对数据进行转换或者应用函数。pipe(), apply(), 和 applymap() 是三个常用的方法,它们使得这些操作变得更加便捷。下面我将逐一详细解释这些方法,并展示如何使用它们。
pipe()
pipe() 方法允许你对整个 DataFrame 应用一个函数。它通常用于链式调用,你可以将前一个方法的输出作为下一个方法的输入。这是一种优雅的数据处理方式,因为它可以使代码更加简洁和可读。
举个例子,假设你有一个数据处理过程,其中需要先对数据进行清洗,然后计算一些统计数据,最后输出结果。你可以将这个过程分解成一系列的函数,然后用 pipe() 将它们链接起来。
import pandas as pd
# 假设这些是你的数据处理函数
def clean_data(df):
# 数据清洗逻辑
return df
def calculate_stats(df):
# 计算统计数据
return df
def output_results(df):
# 输出结果
return df
# 创建一个 DataFrame
df = pd.DataFrame(data)
# 使用 pipe 链接你的函数
result = df.pipe(clean_data).pipe(calculate_stats).pipe(output_results)
apply()
apply() 方法可以沿着DataFrame的某个轴应用一个函数,例如,对每一列或每一行应用一个函数。
import pandas as pd
# 创建一个 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
# 定义一个简单的函数,比如计算最大值和最小值的差
def range_diff(x):
return x.max() - x.min()
# 对每一列应用函数
col_range = df.apply(range_diff, axis=0)
# 对每一行应用函数
row_range = df.apply(range_diff, axis=1)
applymap()
applymap() 是 DataFrame 中的方法,用于对每个元素应用一个给定的函数。这对于元素级的操作非常有用。
import pandas as pd
# 创建一个 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
# 定义一个简单的函数,比如将每个元素乘以 2
def multiply_by_two(x):
return x * 2# 对 DataFrame 的每个元素应用函数
df_transformed = df.applymap(multiply_by_two)
Pandas重建索引
在Pandas中,重建索引(reindexing)是指根据新的索引对原始DataFrame或Series的数据进行重新排列的过程。如果新索引中有原来不存在的标签,会引入缺失数据(通常用NaN表示)。这个过程对于数据的清洗和准备是非常有用的,特别是在你希望对数据集的索引顺序进行改变或者将两个不同索引的数据集合并时。
让我们通过一些例子来详细了解如何使用 reindex 方法。
首先,导入pandas库并创建一个简单的DataFrame:
import pandas as pd
# 创建一个简单的DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
}, index=['a', 'b', 'c'])
print(df)
"""
A B C
a 1 4 7
b 2 5 8
c 3 6 9
"""
重建索引
假设我们想要根据一个新的索引对df进行重建索引:
# 新的索引
new_index = ['c', 'b', 'a', 'd']
# 重建索引
df_reindexed = df.reindex(new_index)
print(df_reindexed)
"""
A B C
c 3.0 6.0 9.0
b 2.0 5.0 8.0
a 1.0 4.0 7.0
d NaN NaN NaN
"""
这里可以看到,根据新索引重建后,原来索引中的行保持了它们的数据,而新引入的索引’label’(如’d’)的行被填充了NaN。
缺失数据的填充
当你重建索引时,你可能不希望缺失值出现。你可以在调用reindex时使用fill_value参数指定一个默认填充值:
# 使用0填充缺失值
df_reindexed_with_fill = df.reindex(new_index, fill_value=0)
print(df_reindexed_with_fill)
"""
A B C
c 3 6 9
b 2 5 8
a 1 4 7
d 0 0 0
"""