目录
- 前言
- 1. DataFrame 简介
- 2. DataFrame的特点
- 3. DataFrame的创建
- 3.1 使用字典创建DataFrame
- 3.2 使用列表的列表(或元组)创建DataFrame
- 3.3 使用NumPy数组创建DataFrame
- 3.4 使用Series构成的字典创建DataFrame
- 3.5 使用字典构成的字典创建DataFrame
- 4. 从 CSV 文件读取
- 5. DataFrame的属性和方法
- 5.1 查看 DataFrame
- 5.2 访问数据
- 5.3 修改数据
- 5.4 DataFrame 的属性
- 5.5 DataFrame 的方法
前言
大家好!我是架构筑梦的Cherry,本期跟大家分享的知识是 pandas 数据结构——DataFrame。
作者的【 Python智能工坊】专栏及【少儿编程Python:趣味编程,探索未来】正在火热更新中🔥🔥🔥,如果本文对您有帮助,欢迎大家点赞 + 评论 + 收藏 !
1. DataFrame 简介
DataFrame
是 pandas 库中最重要的数据结构之一,它用于存储和操作二维标签化的数据结构(即表格型数据)。它的强大功能、灵活性以及易用性,使其成为数据分析领域的重要工具。
在 DataFrame 中,我们可以拥有行(index
)和列(columns
),每个单元格可以包含任何数据类型(如整数、浮点数、字符串、Python 对象等)。
2. DataFrame的特点
-
二维标签化数据结构: DataFrame是一个二维表格型数据结构,具有行和列的标签,允许用户通过索引或列名方便地访问和操作数据。
-
灵活的数据类型: DataFrame中的每一列可以是不同的数据类型,如整数、浮点数、字符串、布尔值等。这使得DataFrame能够存储和处理复杂的数据集。
-
丰富的索引功能: DataFrame支持多级索引,可以通过行标签(index)和列标签(columns)进行快速的数据访问。此外,DataFrame还支持基于条件的索引,允许用户根据特定条件筛选和查询数据。
-
强大的数据处理能力: DataFrame提供了丰富的数据处理功能,包括数据排序、筛选、分组、汇总、连接等。这些功能使得用户能够轻松地对数据进行清洗、转换和分析,以满足不同的数据分析需求。
-
与其他工具的集成: DataFrame可以与许多其他工具和库(如NumPy、SciPy、Matplotlib等)进行集成,为用户提供更加全面和强大的数据处理和可视化功能。
-
易于使用和理解: DataFrame的语法和API设计得非常直观和易于理解,使得用户能够快速上手并熟练掌握其使用方法。同时,pandas库还提供了丰富的文档和示例代码,帮助用户更好地理解和应用DataFrame。
-
高性能和可扩展性: DataFrame在数据处理方面具有很高的性能,能够快速地处理大规模数据集。此外,pandas库还提供了可扩展的接口和工具,允许用户根据自己的需求进行定制和优化。
-
广泛的应用场景: DataFrame广泛应用于数据分析、数据科学、机器学习等领域。无论是在商业智能、金融分析还是科学研究方面,DataFrame都发挥着重要的作用。
3. DataFrame的创建
在pandas库中,DataFrame的创建可以通过多种方式实现,以下是几种常见且清晰的创建方法:
- 使用字典创建DataFrame
- 使用列表的列表(或元组)创建DataFrame
- 使用NumPy数组创建DataFrame
- 使用Series构成的字典创建DataFrame
- 使用字典构成的字典创建DataFrame
pd.DataFrame()是创建DataFrame的常用方法,格式如下:
pd.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)
参数说明:
- data:用于创建 DataFrame 的数据,可以是二维数组、列表的列表、字典等。
- index:指定 DataFrame 的行标签,默认为整数序列。
- columns:指定 DataFrame 的列标签,如果数据中包含列名则无需指定。
- dtype:指定 DataFrame 中列的数据类型。
- copy:是否复制输入数据,默认为 False。
以下是一些关于 DataFrame 的实例:
3.1 使用字典创建DataFrame
这是最直观和常用的创建方式之一。当已经有一组数据并且明确了每列的数据和列名时,可以使用字典来创建DataFrame。
import pandas as pd
# 使用字典列表创建
data = {
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': ['p', 'q', 'r']
}
df = pd.DataFrame(data)
print(df)
输出:
A B C
0 1 4 p
1 2 5 q
2 3 6 r
3.2 使用列表的列表(或元组)创建DataFrame
当数据已经以记录方式(即每条记录是一个列表或元组)组织好,并且只需要添加列名时,可以使用此方法。
import pandas as pd
# 使用列表的列表创建DataFrame
data = [['Alice', 25, 'New York'], ['Bob', 30, 'Paris'], ['Charlie', 35, 'London']]
# 创建DataFrame,并指定列名
df = pd.DataFrame(data, columns=['Name', 'Age', 'City'])
print(df)
输出:
Name Age City
0 Alice 25 New York
1 Bob 30 Paris
2 Charlie 35 London
3.3 使用NumPy数组创建DataFrame
如果已经有NumPy数组,并且想将其转换为DataFrame,可以这样做。
import pandas as pd
import numpy as np
# 创建NumPy数组
nums = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 创建DataFrame,并指定列名和索引
df = pd.DataFrame(nums, columns=['A', 'B', 'C'], index=['row1', 'row2', 'row3'])
print(df)
输出:
A B C
row1 1 2 3
row2 4 5 6
row3 7 8 9
3.4 使用Series构成的字典创建DataFrame
当数据是pandas的Series对象时,也可以将其组合成字典来创建DataFrame。
import pandas as pd
import numpy as np
# 创建Series对象
s1 = pd.Series([1, 2, 3], name='A')
s2 = pd.Series([4, 5, 6], name='B')
# 创建DataFrame
df = pd.DataFrame({'A': s1, 'B': s2})
print(df)
输出:
A B
0 1 4
1 2 5
2 3 6
3.5 使用字典构成的字典创建DataFrame
此方法适用于数据是嵌套的字典结构,外层的字典键作为列名,内层的字典键作为行索引。
import pandas as pd
# 嵌套字典数据
data = {
'a': {'一': 1, '二': 2},
'b': {'一': 10, '二': 20},
'c': {'一': 100, '二': 200}
}
# 创建DataFrame
df = pd.DataFrame(data)
print(df)
输出:
a b c
一 1 10 100
二 2 20 200
这些方法是创建DataFrame的常见方式,可以根据具体的数据结构和需求选择最适合的方法。
4. 从 CSV 文件读取
在pandas库中,从CSV(Comma Separated Values)文件读取数据以创建DataFrame是非常常见的操作。这可以通过pd.read_csv()函数来实现。以下是一些使用pd.read_csv()函数的基本示例和参数说明:
import pandas as pd
# 读取CSV文件
df = pd.read_csv('file.csv')
# 显示DataFrame内容
print(df)
pd.read_csv()函数有很多参数可以定制读取行为,以下是一些常用的参数:
- filepath_or_buffer:文件路径或类似文件的对象。这是必须的参数。
- sep 或 delimiter:字段分隔符,默认为,。如果你的CSV文件使用其他分隔符(如制表符\t),你需要更改这个参数。
- header:用作列名的行号。默认为0(即第一行)。如果CSV文件没有标题行,可以设置为None,并使用names参数手动指定列名。
- names:如果数据不包含列标题,则可以使用此参数指定列名列表。
- index_col:用作行索引的列编号或列名。如果未指定,则使用默认的整数索引。
- usecols:返回列的子集。可以是列名的列表,也可以是列编号的列表。
- dtype:列的数据类型。可以是单个类型,也可以是为每列指定的字典。
- nrows:要读取的行数。这对于大文件特别有用,因为可以只读取前几行进行快速测试。
- skiprows:要跳过的行数(从文件开始处计算)。
- encoding:用于文件解码的字符编码。例如,‘utf-8’。
- parse_dates:尝试将数据解析为日期。可以是布尔值,表示是否尝试解析所有列,也可以是列名的列表或解析指令的列表。
- keep_default_na:如果指定了na_values参数,并且keep_default_na为False,则忽略默认的NaN值(如空字符串)。
- na_values:识别为NaN或None的附加字符串列表。
- thousands:用于解析数字的千位分隔符,如’,‘或’.'。
- skipinitialspace:跳过字段中前导的空白字符。
- comment:标记要忽略的行。任何包含此行标记的行都将被忽略。
5. DataFrame的属性和方法
5.1 查看 DataFrame
* 使用 `print(df)` 或直接在 Jupyter Notebook 中查看
* 使用 `df.head(n)` 查看前 n 行(默认为 5 行)
* 使用 `df.tail(n)` 查看后 n 行
- 示例 1: 使用 print(df) 或直接在 Jupyter Notebook 中查看
在Jupyter Notebook中,通常不需要显式调用print(df)来显示DataFrame。您只需将变量df(在这里它引用了您的DataFrame)作为一个独立的表达式或作为最后一行写入一个代码单元格,然后运行该单元格。Jupyter Notebook将自动显示df的内容。
import pandas as pd
# 假设我们有一个名为'example.csv'的CSV文件
df = pd.read_csv('example.csv')
# 在Jupyter Notebook中,只需运行以下行(无需print)
df
注意:如果您在标准的Python脚本或交互式环境中工作,则需要使用print(df)来显示DataFrame的内容。
- 示例 2: 使用 df.head(n) 查看前 n 行(默认为 5 行)
df.head(n)函数允许您查看DataFrame的前n行。如果未指定n,则默认显示前5行。
import pandas as pd
# 假设我们有一个名为'example.csv'的CSV文件
df = pd.read_csv('example.csv')
# 显示前5行(默认)
print(df.head())
# 显示前10行
print(df.head(10))
- 示例 3: 使用 df.tail(n) 查看后 n 行
类似地,df.tail(n)函数允许您查看DataFrame的最后n行。如果未指定n,则默认显示最后5行。
import pandas as pd
# 假设我们有一个名为'example.csv'的CSV文件
df = pd.read_csv('example.csv')
# 显示最后5行(默认)
print(df.tail())
# 显示最后10行
print(df.tail(10))
5.2 访问数据
* 通过列名访问整列数据:`df['A']`
* 通过位置访问列:`df.iloc[:, 0]` (等价于 `df['A']` 但基于位置)
* 通过标签访问列:`df.loc[:, 'A']` (也等价于 `df['A']` 但基于标签)
* 访问单个元素:`df.at[row_label, 'A']` 或 `df.iat[row_position, 0]`
* 访问多行多列:使用切片或布尔索引
- 示例1:通过列名访问整列数据
# 假设我们有一个DataFrame df,它有一个名为'A'的列
col_a = df['A']
- 示例2:通过位置访问列
# 使用iloc基于整数位置索引访问第一列(位置为0的列)
# 注意这不一定等同于df['A'],除非'A'确实是第一列
col_by_position = df.iloc[:, 0]
- 示例3:通过标签访问列
# 使用loc基于标签索引访问名为'A'的列
# 这与df['A']等效
col_by_label = df.loc[:, 'A']
- 示例4:访问单个元素
有两种主要方式访问单个元素:
使用.at[]基于标签:
# 假设我们想要访问标签为'row_label'的行和名为'A'的列中的元素
element_at = df.at['row_label', 'A']
使用.iat[]基于整数位置:
# 假设我们想要访问第一行(位置为0)和第一列(位置为0)中的元素
# 注意这通常不会直接对应于'A'列,除非'A'是第一列,且'row_label'是第一行的标签
element_iat = df.iat[0, 0]
# 但如果你知道'A'是第n列,可以这样访问:
n = df.columns.get_loc('A') # 获取'A'列的整数位置
row_position = 0 # 假设要访问第一行
element_specific_iat = df.iat[row_position, n]
- 示例5:访问多行多列
– 使用切片
# 访问前两行和前两列(基于位置)
subset_by_slice = df.iloc[:2, :2]
# 访问名为'A'和'B'的列(基于标签)
subset_by_slice_label = df.loc[:, ['A', 'B']]
– 使用布尔索引
# 假设我们有一个条件来选择某些行(例如,'A'列的值大于10)
mask = df['A'] > 10
# 选择满足条件的行和所有列
subset_by_condition = df[mask]
# 或者,选择满足条件的行和特定的列(例如,'B'和'C'列)
subset_by_condition_and_columns = df.loc[mask, ['B', 'C']]
5.3 修改数据
* 直接修改列的值:`df['A'] = [10, 20, 30]`
* 添加新列:`df['D'] = [100, 200, 300]`
* 删除列:`del df['A']` 或 `df = df.drop(columns=['A'])`
* 删除行:`df = df.drop(index=[0, 1])` (注意这会改变原始的 index)
- 示例1:直接修改列的值
import pandas as pd
# 创建一个简单的 DataFrame
data = {
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
}
df = pd.DataFrame(data)
df['A'] = [10, 20, 30]
print("\n修改列 'A' 后的 DataFrame:")
print(df)
输出:
A B C
0 10 4 7
1 20 5 8
2 30 6 9
- 示例2:添加新列
df['D'] = [100, 200, 300]
print("\n添加新列 'D' 后的 DataFrame:")
print(df)
输出:
A B C D
0 10 4 7 100
1 20 5 8 200
2 30 6 9 300
- 示例3:删除列
del df['A']
print("\n使用 del 删除列 'A' 后的 DataFrame:")
print(df)
输出:
B C D
0 4 7 100
1 5 8 200
2 6 9 300
- 示例4:使用 drop 方法
df = df.drop(columns=['B'])
print("\n使用 drop 方法删除列 'B' 后的 DataFrame:")
print(df)
输出:
C D
0 7 100
1 8 200
2 9 300
- 示例5:删除行
df = df.drop(index=[0, 1])
print("\n删除索引为 0 和 1 的行后的 DataFrame:")
print(df)
输出:
C D
2 9 300
注意:在删除行或列后,原始的 index 可能会被改变(取决于你是否重置了 index)。如果你希望保留原始的 index 值(即使行被删除),你可能需要使用 reset_index 方法并设置 drop=True 来避免旧的 index 成为 DataFrame 的一部分。
5.4 DataFrame 的属性
* `df.shape`:返回 DataFrame 的形状(行数,列数)
* `df.dtypes`:返回每列的数据类型
* `df.index`:返回行标签
* `df.columns`:返回列标签
* `df.values`:返回 DataFrame 的 ndarray 表示
- 示例:
import pandas as pd
# 创建一个简单的 DataFrame
data = {
'A': [1, 2, 3],
'B': [4.0, 5.0, 6.0],
'C': ['foo', 'bar', 'baz'],
'D': pd.date_range(start='2023-01-01', periods=3)
}
df = pd.DataFrame(data)
# 获取 DataFrame 的形状(行数,列数)
print("Shape of DataFrame:", df.shape) # 输出:Shape of DataFrame: (3, 4)
# 获取每列的数据类型
print("Data types of columns:", df.dtypes) # 输出:Data types of columns: A int64
# B float64
# C object
# D datetime64[ns]
# dtype: object
# 获取行标签
print("Row labels (index):", df.index) # 输出:Row labels (index): RangeIndex(start=0, stop=3, step=1)
# 获取列标签
print("Column labels:", df.columns) # 输出:Column labels: Index(['A', 'B', 'C', 'D'], dtype='object')
# 获取 DataFrame 的 ndarray 表示
print("NumPy ndarray representation:", df.values)
# 输出:
# NumPy ndarray representation: [[1 4.0 'foo' Timestamp('2023-01-01 00:00:00')]
# [2 5.0 'bar' Timestamp('2023-01-02 00:00:00')]
# [3 6.0 'baz' Timestamp('2023-01-03 00:00:00')]]
5.5 DataFrame 的方法
* `df.describe()`:提供 DataFrame 的统计摘要
* `df.sort_values(by='column_name')`:按指定列的值排序
* `df.groupby('column_name')`:按指定列的值进行分组
* `df.merge(other_df, on='column_name')`:基于指定列合并两个 DataFrame
* `df.pivot(index='column1', columns='column2', values='column3')`:将数据重塑为表格格式
当然,以下是您给出的 pandas DataFrame 操作的示例:
- 示例1:df.describe() :提供 DataFrame 的统计摘要
import pandas as pd
# 创建一个简单的 DataFrame
data = {
'A': [1, 2, 3, 4, 5],
'B': [10, 20, 30, 20, 15],
'C': [100, 200, 50, 30, 20]
}
df = pd.DataFrame(data)
# 提供 DataFrame 的统计摘要
print(df.describe())
输出:
A B C
count 5.000000 5.000000 5.000000
mean 3.000000 19.000000 80.000000
std 1.581139 7.416198 73.824115
min 1.000000 10.000000 20.000000
25% 2.000000 15.000000 30.000000
50% 3.000000 20.000000 50.000000
75% 4.000000 20.000000 100.000000
max 5.000000 30.000000 200.000000
这将输出每列的基本统计信息,如计数、均值、标准差、最小值、25%分位数、中位数、75%分位数和最大值。
- 示例2:df.sort_values(by=‘column_name’):按指定列的值排序
# 按列 'B' 的值排序
sorted_df = df.sort_values(by='B')
print(sorted_df)
这将按 ‘B’ 列的值对 DataFrame 进行排序。
输出:
A B C
0 1 10 100
4 5 15 20
3 4 20 30
1 2 20 200
2 3 30 50
- 示例3:df.groupby(‘column_name’):按指定列的值进行分组
# 按列 'B' 的值进行分组,并计算每组的 'A' 列的均值
grouped = df.groupby('B')['A'].mean()
print(grouped)
这将根据 ‘B’ 列的值对 DataFrame 进行分组,并计算每个组中 ‘A’ 列的均值。
输出:
B
10 1.0
15 5.0
20 3.0
30 3.0
Name: A, dtype: float64
- 示例4:df.merge(other_df, on=‘column_name’):基于指定列合并两个 DataFrame
# 创建另一个 DataFrame
other_data = {
'B': [20, 15, 30, 20],
'D': ['x', 'y', 'z', 'w']
}
other_df = pd.DataFrame(other_data)
# 基于 'B' 列合并两个 DataFrame
merged_df = df.merge(other_df, on='B')
print(merged_df)
这将基于 ‘B’ 列的值将两个 DataFrame 合并为一个新的 DataFrame。
输出:
A B C D
0 2 20 200 x
1 2 20 200 w
2 3 30 50 z
3 4 20 30 x
4 4 20 30 w
5 5 15 20 y
- 示例5:df.pivot(index=‘column1’, columns=‘column2’, values=‘column3’):将数据重塑为表格格式
# 假设我们有一个如下的 DataFrame
pivot_data = {
'year': [2020, 2020, 2021, 2021],
'product': ['A', 'B', 'A', 'B'],
'sales': [100, 200, 150, 300]
}
pivot_df = pd.DataFrame(pivot_data)
# 使用 pivot 方法将数据重塑为表格格式
pivoted_df = pivot_df.pivot(index='year', columns='product', values='sales')
print(pivoted_df)
这将根据 ‘year’ 列的值创建行,根据 ‘product’ 列的值创建列,并将 ‘sales’ 列的值填入对应的单元格中。如果数据不能唯一地确定每个单元格的值(即存在重复的行/列组合),则 pivot
方法会抛出错误。在这种情况下,可以使用 pivot_table
方法,它允许进行聚合操作。
输出:
product A B
year
2020 100 200
2021 150 300