(6) 深入探索Python-Pandas库的核心数据结构: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
  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码界领航

你的鼓励将是我最最大的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值