大家好!我是架构筑梦的Cherry,本期跟大家分享的知识是 pandas 数据结构——DataFrame。
作者的【 Python智能工坊】专栏及【少儿编程Python:趣味编程,探索未来】正在火热更新中,如果本文对您有帮助,欢迎大家点赞 + 评论 + 收藏 !
DataFrame
是 pandas 库中最重要的数据结构之一,它用于存储和操作二维标签化的数据结构(即表格型数据)。它的强大功能、灵活性以及易用性,使其成为数据分析领域的重要工具。
在 DataFrame 中,我们可以拥有行(index
)和列(columns
),每个单元格可以包含任何数据类型(如整数、浮点数、字符串、Python 对象等)。
二维标签化数据结构: DataFrame是一个二维表格型数据结构,具有行和列的标签,允许用户通过索引或列名方便地访问和操作数据。
灵活的数据类型: DataFrame中的每一列可以是不同的数据类型,如整数、浮点数、字符串、布尔值等。这使得DataFrame能够存储和处理复杂的数据集。
丰富的索引功能: DataFrame支持多级索引,可以通过行标签(index)和列标签(columns)进行快速的数据访问。此外,DataFrame还支持基于条件的索引,允许用户根据特定条件筛选和查询数据。
强大的数据处理能力: DataFrame提供了丰富的数据处理功能,包括数据排序、筛选、分组、汇总、连接等。这些功能使得用户能够轻松地对数据进行清洗、转换和分析,以满足不同的数据分析需求。
与其他工具的集成: DataFrame可以与许多其他工具和库(如NumPy、SciPy、Matplotlib等)进行集成,为用户提供更加全面和强大的数据处理和可视化功能。
易于使用和理解: DataFrame的语法和API设计得非常直观和易于理解,使得用户能够快速上手并熟练掌握其使用方法。同时,pandas库还提供了丰富的文档和示例代码,帮助用户更好地理解和应用DataFrame。
高性能和可扩展性: DataFrame在数据处理方面具有很高的性能,能够快速地处理大规模数据集。此外,pandas库还提供了可扩展的接口和工具,允许用户根据自己的需求进行定制和优化。
广泛的应用场景: DataFrame广泛应用于数据分析、数据科学、机器学习等领域。无论是在商业智能、金融分析还是科学研究方面,DataFrame都发挥着重要的作用。
在pandas库中,DataFrame的创建可以通过多种方式实现,以下是几种常见且清晰的创建方法:
pd.DataFrame()是创建DataFrame的常用方法,格式如下:
pd.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)
参数说明:
以下是一些关于 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
当数据已经以记录方式(即每条记录是一个列表或元组)组织好,并且只需要添加列名时,可以使用此方法。
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
如果已经有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
当数据是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
此方法适用于数据是嵌套的字典结构,外层的字典键作为列名,内层的字典键作为行索引。
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的常见方式,可以根据具体的数据结构和需求选择最适合的方法。
在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()函数有很多参数可以定制读取行为,以下是一些常用的参数:
* 使用 `print(df)` 或直接在 Jupyter Notebook 中查看
* 使用 `df.head(n)` 查看前 n 行(默认为 5 行)
* 使用 `df.tail(n)` 查看后 n 行
import pandas as pd
# 假设我们有一个名为'example.csv'的CSV文件
df = pd.read_csv('example.csv')
# 在Jupyter Notebook中,只需运行以下行(无需print)
df
注意:如果您在标准的Python脚本或交互式环境中工作,则需要使用print(df)来显示DataFrame的内容。
import pandas as pd
# 假设我们有一个名为'example.csv'的CSV文件
df = pd.read_csv('example.csv')
# 显示前5行(默认)
print(df.head())
# 显示前10行
print(df.head(10))
import pandas as pd
# 假设我们有一个名为'example.csv'的CSV文件
df = pd.read_csv('example.csv')
# 显示最后5行(默认)
print(df.tail())
# 显示最后10行
print(df.tail(10))
* 通过列名访问整列数据:`df['A']`
* 通过位置访问列:`df.iloc[:, 0]` (等价于 `df['A']` 但基于位置)
* 通过标签访问列:`df.loc[:, 'A']` (也等价于 `df['A']` 但基于标签)
* 访问单个元素:`df.at[row_label, 'A']` 或 `df.iat[row_position, 0]`
* 访问多行多列:使用切片或布尔索引
# 假设我们有一个DataFrame df,它有一个名为'A'的列
col_a = df['A']
# 使用iloc基于整数位置索引访问第一列(位置为0的列)
# 注意这不一定等同于df['A'],除非'A'确实是第一列
col_by_position = df.iloc[:, 0]
# 使用loc基于标签索引访问名为'A'的列
# 这与df['A']等效
col_by_label = df.loc[:, 'A']
使用.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]
# 访问前两行和前两列(基于位置)
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']]
* 直接修改列的值:`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)
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
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
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
df = df.drop(columns=['B'])
print("\n使用 drop 方法删除列 'B' 后的 DataFrame:")
print(df)
输出:
C D
0 7 100
1 8 200
2 9 300
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 的一部分。
* `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')]]
* `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 操作的示例:
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%分位数和最大值。
# 按列 '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
# 按列 '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
# 创建另一个 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
# 假设我们有一个如下的 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