python Pandas 操作

 Pandas 介绍

Pandas 是一个功能强大的 Python 数据分析工具库,常用于数据处理与分析工作。它为 Python 提供了快速、灵活以及表达能力强的数据结构,旨在简化“实际工作中”的数据操作,使得 Python 成为一种强大而高效的数据分析环境。

核心特性

  1. 数据结构:

    • Series:一维标签数组,能够存储任意数据类型(整数、字符串、浮点数、Python 对象等)。轴标签统称为索引。
    • DataFrame:二维标签数据结构,可以看作是具有共同索引的 Series 的集合。
  2. 处理数据:

    • 读写不同格式的数据(CSV、Excel、数据库、HDF5等)。
    • 清洗数据,如处理丢失数据(NA值)、删除重复值。
    • 数据过滤、筛选、以及转换。
    • 强大的数据聚合和转换功能。
  3. 数据对齐与缺失数据

    • 自动与显式数据对齐。对象之间的操作通常会对齐数据,并在必要时透明地处理缺失数据。
    • 灵活处理缺失数据或不规则数据,并轻松地填充缺失数据或对数据进行插值。
  4. 时间序列

    • 简单、强大且高效的功能来执行时间序列数据的操作,如生成日期范围、转换频率、移动窗口统计等。
  5. 合并/连接数据集

    • 高效地对齐索引以连接/合并多个数据集。
    • 提供多种方式来合并和连接数据集,如按索引合并、按列合并等。
  6. 分组操作

    • "拆分-应用-组合"操作使数据集可以被分组,并对每组应用一个函数,然后将结果合并回一起。
  7. 灵活的重塑与透视

    • 能够轻松地重塑(堆叠和展开)和透视数据表。
  8. 高性能

    • Pandas 的底层依赖于 NumPy(一种用于高效数学计算的 Python 库),使得 pandas 在处理大数据时保持良好的性能。

应用场景

Pandas 被广泛用于各种领域中的数据分析任务,包括但不限于金融、经济学、统计学、广告、Web 分析等。它是数据科学与机器学习项目中数据探索与清洗的重要工具。通过与诸如 NumPy、SciPy、Matplotlib、scikit-learn 和 statsmodels 等库的结合使用,pandas 提供了一个强大的环境,用于更广泛的科学计算应用。

为什么选择 Pandas?

选择使用 pandas 的原因很多,其核心优势在于它提供了一种高效、直观且高层的 API,使得数据操作和分析变得快捷和容易。Pandas 的设计目标就是简化复杂的数据操作,减少数据处理任务的编程负担。

如果你需要在 Python 中进行数据分析或数据处理,学习和使用 pandas 无疑是一个值得的投资。它将帮助你更高效地完成数据分析任务,释放出更多时间来关注数据的洞察与解释。

  1. 安装 Pandas:

    pip install pandas
    
  2. 导入 Pandas:

    import pandas as pd

1. 创建 Pandas 数据结构

Pandas 有两种主要的数据结构:Series, DataFrame, 和单个元素(标量)。这些结构是构建和管理数据的基础。下面是对每一种数据结构的详细介绍:

1. Series 对象

Series 是一种一维的数组型对象,它包含了一个值序列(与NumPy的数组类似),并且每个值都有一个索引。索引在默认情况下是从0开始的整数,但也可以显式定义为其他类型的值(如字符串、日期等)。Series 可以被看作是一个定长、定序的字典,因为它是索引值到数据值的一个映射。

特点

  • 一维数组Series 是一个一维数组结构,可以存储各种类型的数据(整数、字符串、浮点数、Python对象等)。
  • 索引:每个 Series 对象都有一个索引,索引链接到每个数据点。索引可以是数字系列,也可以是标签(如字符串)。

结构

  • 数据值(data values)
  • 索引(index)

应用

由于每个 Series 对象都可以看作是数据表中的一列,它常常被用于表达数据表中的单个特征。例如,如果有一个包含多个人员信息的 DataFrame,其中可能包括姓名、年龄、城市等,这里的每一列(如“年龄”列)都可以被单独提取出来作为一个 Series 对象进行处理。

Series 是一维数据结构。 

s = pd.Series([1, 3, 5, 7, 9]) 
print(s)

2.DataFrame

DataFrame 是二维的表格型数据结构,非常类似于 Excel 表格。可以看作是Series 对象的容器。DataFrame 有行索引和列索引,每列可以是不同的值类型(数值、字符串、布尔值等),它既可以作为一个整体被高效地处理,也可以逐块进行处理。

data = {'Name': ['Tom', 'Jerry', 'Mickey'],'Age': [20, 21, 22],'Salary': [7000, 8000, 9000]}
df = pd.DataFrame(data)

3. 单个元素(标量)

在pandas中处理数据时,访问DataFrame或Series的单个值会返回一个标量。这个标量通常是Python原生数据类型(如int、float、str等)或者NumPy数据类型,取决于数据的具体类型。当你从DataFrameSeries中索引单个数据时,返回的就是一个标量。

1.创建df 依据 现有的字符串列名 和列表变量

要创建一个 DataFrame 依据现有的字符串列名和列表变量,你可以使用 Pandas 的 pd.DataFrame 函数,并传入一个字典,其中键是列名,值是相应的列表。每个列表的长度应该相同,因为它将对应于 DataFrame 的每一行。

以下是一个例子:

import pandas as pd# 假设我们有以下列名
column_names = ['Name', 'Age', 'Salary']# 和相应的列表变量
names = ['Tom', 'Jerry', 'Mickey']
ages = [20, 21, 22]
salaries = [7000, 8000, 9000]# 创建一个字典,将列名映射到列表
data = {'Name': names, 'Age': ages, 'Salary': salaries}# 使用这个字典创建 DataFrame
df = pd.DataFrame(data)print(df)

2.添加一行数据

在 pandas DataFrame 中添加一行数据可以通过多种方法完成,包括使用 append() 方法或直接使用 loc 索引器。下面是两种常见的方法来添加一行数据到现有的 DataFrame。

方法 1:使用 append()

append() 方法可以用来向 DataFrame 添加新行。这种方法在 pandas 的新版本中已经不推荐使用(建议使用 concat()),但它仍然是一个简单直观的方法。以下是如何使用 append() 方法:

import pandas as pd# 假设已有的 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35],'City': ['New York', 'Boston', 'Los Angeles']
}
df = pd.DataFrame(data)# 创建一个新行的数据
new_row = {'Name': 'David', 'Age': 28, 'City': 'Miami'}# 使用 append 方法添加行
df = df.append(new_row, ignore_index=True)print(df)

方法 2:使用 loc[]

如果你知道新行的索引,可以直接使用 loc[] 索引器来添加或修改行。这种方法对于在特定位置插入数据特别有用:

import pandas as pd# 假设已有的 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35],'City': ['New York', 'Boston', 'Los Angeles']
}
df = pd.DataFrame(data)# 使用 loc 方法添加行
df.loc[len(df)] = ['David', 28, 'Miami']print(df)

输出结果

执行上述代码后,你的 DataFrame 将包括一个新添加的行:

loc[] 索引器详解

loc[] 是一个基于标签的索引器,你可以使用它来访问 DataFrame 中的行或列。在添加行的情况下:

  • 索引: 用 len(df) 来确定新行的索引位置。因为 Python 的索引从0开始,len(df) 总是指向当前 DataFrame 中下一个空闲的行位置。这是因为 len(df) 返回的是 DataFrame 的行数,正好也是新添加行的索引(因为索引从0开始计数)。

方法 3:使用 concat()

推荐的方法是使用 concat(),特别是当需要添加多行数据时。这里是如何用 concat() 添加单行的例子:

import pandas as pd# 假设已有的 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35],'City': ['New York', 'Boston', 'Los Angeles']
}
df = pd.DataFrame(data)# 创建一个新行的 DataFrame
new_row = pd.DataFrame([['David', 28, 'Miami']], columns=['Name', 'Age', 'City'])# 使用 concat 方法添加行
df = pd.concat([df, new_row], ignore_index=True)print(df)

3.添加列数据

在 pandas DataFrame 中添加列数据是一个常见的数据处理操作,可以根据特定的需求以多种方式完成。以下是几种向 DataFrame 添加新列的基本方法:

方法 1:直接赋值

最直接的方法是使用列名称和一个值或一系列值来为 DataFrame 添加列。如果你提供单一值,pandas 会将这个值广播到整个列中。如果提供的是一个列表或系列,那么这些值将逐行填充。

import pandas as pd# 假设已有的 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35]
}
df = pd.DataFrame(data)# 添加一个新列,所有行的值都是同一个值
df['Sex'] = 'Female'# 添加一个新列,每行的值不同
df['Salary'] = [50000, 60000, 70000]print(df)

方法 2:使用 assign()

assign() 方法可以在不修改原始 DataFrame 的情况下添加新列。这是一个非常有用的功能,特别是在链式调用中。

import pandas as pd# 假设已有的 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35]
}
df = pd.DataFrame(data)# 使用 assign 方法添加一个列名为 ‘Salary’ 的新列, 传递一个包含三个整数的列表 [50000, 60000, 70000]。这三个数值将分别对应 DataFrame 中三行的薪资信息。
df = df.assign(Salary=[50000, 60000, 70000])# 使用 assign 方法添加一个列名为 'Sex' 的新列,这列的值对于所有行都是相同的,即 'Female'。由于我们提供了一个单一的字符串,pandas 将这个值广播到 DataFrame 的每一行。
df = df.assign(Sex='Female')#同时添加两列# 准备添加的全新列数据
birthdates = ['1995-02-15', '1988-08-23', '1993-07-04']  # 出生日期
job_titles = ['Engineer', 'Designer', 'Manager']  # 职务# 使用 assign 方法同时添加两个完全新的列
df = df.assign(Birthdate=birthdates, JobTitle=job_titles)print(df)

方法 3:使用 insert()

如果你需要在特定的位置插入一列,可以使用 insert() 方法。你可以指定列的位置(索引号),列的名称和列的值。

import pandas as pd# 假设已有的 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35]
}
df = pd.DataFrame(data)# 使用 insert 方法在指定位置插入新列
df.insert(1, 'Sex', 'Female')print(df)

输出结果

执行上述代码后,你的 DataFrame 将包含一个新的列 "Sex",位置在 "Name" 列之后,"Age" 列之前:

insert() 方法详解

insert() 方法的调用格式如下:

DataFrame.insert(loc, column, value, allow_duplicates=False)
  • loc: 整数,指定了新列插入的位置的索引。索引 0 表示最前面,len(df.columns) 表示最后面。在我们的例子中,1 表示新列将放在第二的位置(索引从 0 开始计数)。
  • column: 字符串,是新添加的列的名称。
  • value: 可以是单个值或与 DataFrame 行数相等的数组。如果是单个值,它将被广播到所有行。
  • allow_duplicates: 布尔值,默认为 False。如果设置为 True,允许插入名称已存在的列。

索引的重要性

在使用 insert() 方法时,选择正确的索引是关键。索引值决定了新列将出现在 DataFrame 中的哪个位置。这对于数据的展示顺序非常重要,尤其是在准备数据报告或执行数据可视化时。调整 loc 参数,你可以精确控制列的插入位置。

方法 4:使用字典扩展

如果新列的数据是通过现有列计算得出的,你也可以通过字典方式添加新列。例如,我们基于年龄添加一个描述列:

import pandas as pd# 假设已有的 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35]
}
df = pd.DataFrame(data)# 添加新列,基于其他列的数据
df['Age Group'] = df['Age'].apply(lambda x: 'Young' if x < 30 else 'Adult')print(df)

4. 数据的读取和写入

读取 CSV 文件
df = pd.read_csv('filename.csv')

1.写入 CSV 文件

使用 to_csv() 方法将 DataFrame 数据导出到 CSV 文件,同时指定编码为 UTF-8。

df.to_csv('output.csv', index=False, encoding='utf-8-sig')

参数解释

  • index=False: 这个参数确保不将 DataFrame 的索引作为一列数据写入 CSV 文件中。如果你想保留索引,可以将此参数设置为 True
  • encoding='utf-8-sig': 这个参数指定文件的编码。使用 'utf-8-sig' 而非 'utf-8' 是为了在某些情况下避免出现带有 BOM(字节顺序标记)的问题,这在一些老旧的程序或系统中读取 UTF-8 编码的文件时可能会遇到。这样可以确保文件的兼容性更强。

2.写入到 Excel 文件

将数据从 pandas DataFrame 写入到 Excel 文件,你可以使用 to_excel() 方法。这是一个非常有用的功能,尤其是当你需要与不熟悉编程的同事共享数据时。下面是如何使用 to_excel() 方法将 DataFrame 数据写入 Excel 文件的步骤:

1. 首先,确保安装了 openpyxl

pandasto_excel() 方法依赖于 openpyxl(或 xlsxwriter)库来写入 Excel 文件(.xlsx)。如果你还没有安装这些库,可以通过以下命令安装:

pip install openpyxl

2. 使用 to_excel() 方法

以下是将 DataFrame 写入 Excel 文件的基本语法:

import pandas as pd# 创建一个示例 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35],'City': ['New York', 'Boston', 'Los Angeles']
}
df = pd.DataFrame(data)# 写入到 Excel 文件
df.to_excel('output.xlsx', sheet_name='Sheet1', index=False)

详细参数说明

  • 文件名: 'output.xlsx' 是要写入的文件名。
  • sheet_name: 'Sheet1' 是工作表的名称。
  • index: 设置为 False 以避免将 DataFrame 的索引也写入到 Excel 文件中。如果你希望索引也被写入,可以设置为 True

3. 进阶选项

  • 多个工作表:你可以将不同的 DataFrames 写入到同一个 Excel 文件的不同工作表中。

     
    import pandas as pd# 创建第一个DataFrame
    data1 = {'Column1': [1, 2, 3],'Column2': ['A', 'B', 'C']
    }
    df = pd.DataFrame(data1)# 创建第二个DataFrame
    data2 = {'Column1': [4, 5, 6],'Column2': ['D', 'E', 'F']
    }
    df2 = pd.DataFrame(data2)# 将两个DataFrame写入同一个Excel文件的不同工作表
    with pd.ExcelWriter('output.xlsx', engine='openpyxl') as writer:df.to_excel(writer, sheet_name='Sheet1', index=False)df2.to_excel(writer, sheet_name='Sheet2', index=False)
    

  • 指定列写入:如果你只想写入某些特定的列,可以在 to_excel() 方法中使用 columns 参数。

     
    df.to_excel('output.xlsx', sheet_name='Sheet1', columns=['Name', 'City'], index=False)
    

5. pandas 中的不同数据访问和修改方法

行列选择 [] ,loc[],iloc[]
单个元素 at[] ,iat[]

这里的标签就是列名称,位置就是已知行列索引位置时

方法描述最佳使用场景示例代码
[]直接访问列当需要访问一个或多个列,且不涉及行选择时。df['Age']df[['Name', 'City']]
loc[]基于标签的索引器需要通过行标签或列标签选择数据,或使用条件表达式选择行时。df.loc[0]df.loc[:, 'Name']df.loc[df['Age'] > 30]
iloc[]基于位置的索引器需要通过行列的位置(整数索引)快速访问数据时。df.iloc[0]df.iloc[:, 1]df.iloc[1:3, 0:2]
at[]快速访问单个元素(基于标签)当确切知道所需数据的标签,并且频繁访问单个元素时。df.at[0, 'Age']
iat[]快速访问单个元素(基于位置)当确切知道所需数据的位置索引,并且频繁访问单个元素时。df.iat[0, 1]
query()使用字符串表达式查询 DataFrame处理复杂的查询逻辑时,能提供更清晰和简洁的语法。df.query('Age > 30')
布尔索引直接根据条件过滤需要根据条件动态过滤行时,特别是处理大型数据集时。df[df['Age'] > 30]
where()保留满足条件的数据,其他为 NaN当需要保留满足条件的数据同时标记不满足条件的数据时。df.where(df['Age'] > 30)
mask()替换满足条件的数据为 NaN当需要隐藏或替换满足条件的数据,同时保留不满足条件的数据时。df.mask(df['Age'] > 30)

 1.使用场景详解:

  • []:适用于快速简单地访问列,或进行列的简单操作(如添加新列)。
  • loc[]:非常适合处理需要根据标签索引进行选择的情况,如选择特定行数据或基于条件选择某些行。
  • iloc[]:当你不需要考虑 DataFrame 的实际索引标签,只需要根据数据的位置进行操作时,iloc[] 是最佳选择。
  • at[]iat[]:这两种方法是访问单个元素的最快方法,特别适合在循环或迭代中频繁访问单个数据点。
  • query():当查询条件较复杂,或者希望使代码更易于阅读和维护时,使用 query() 可以使代码更加优雅。
  • 布尔索引:适用于基于复杂逻辑条件进行数据筛选,特别是当条件涉及多个列时。
  • where()mask():这两个方法提供了一种灵活的方式来处理 DataFrame 数据的可视化或预处理,允许通过条件逻辑保留或替换数据。

2.示例代码详解:

  1. []:

    • 单列访问:df['Age'] — 这行代码返回包含DataFrame中所有'Age'列数据的Series。
    • 多列访问:df[['Name', 'City']] — 这行代码返回一个新的DataFrame,仅包含'Name'和'City'这两列。
  2. loc[]:

    • 单行访问:df.loc[0] — 返回DataFrame中索引为0的行。
    • 单列访问:df.loc[:, 'Name'] — 返回DataFrame中所有行的'Name'列。
    • 条件访问:df.loc[df['Age'] > 30] — 返回所有'Age'大于30的行组成的DataFrame。
  3. iloc[]:

    • 单行访问:df.iloc[0] — 返回DataFrame中第一行的数据。
    • 列访问:df.iloc[:, 1] — 返回DataFrame中第二列的所有数据。
    • 范围访问:df.iloc[1:3, 0:2] — 返回DataFrame从第二行到第三行,从第一列到第二列的数据。
  4. at[]iat[]:

    • df.at[0, 'Age'] — 快速访问第一行的'Age'列的值。这是访问单个值的最快方式,适用于已知行列标签时。
    • df.iat[0, 1] — 快速访问第一行第二列的值。使用位置而不是标签进行访问,适用于已知行列索引位置时。
  5. query():

    • 使用字符串表达式查询年龄大于30的行:df.query('Age > 30') — 这行代码利用一个字符串表达式来过滤DataFrame,返回所有'Age'大于30的行。
  6. 布尔索引:

    • 选择年龄大于30的所有行:df[df['Age'] > 30] — 直接使用条件表达式过滤DataFrame,返回满足条件的行。
  7. where():

    • df.where(df['Age'] > 30) — 这行代码返回一个新的DataFrame,其中不满足条件的行会被替换为NaN值。适用于需要保留数据结构同时标记不符合条件的数据时。
  8. mask():

    • df.mask(df['Age'] > 30) — 相反地,这行代码返回一个新的DataFrame,其中满足条件的行的数据会被替换为NaN值。这可以用于隐藏或删除某些数据

6. loc[] 详解

loc[] 索引器是 pandas 中非常强大的工具,它允许你通过标签来访问和修改 DataFrame 的行和列。下面我会详细解释如何使用 loc[] 来访问和操作特定的行和列。

loc根据访问对象返回不同的类型

  • 当使用 .loc 来访问单个元素时,它会返回该元素的值。
  • 如果选择一行或一列数据,.loc 通常返回一个 Series 对象。
  • 如果选择行和列的特定子集,.loc 返回的是一个 DataFrame 对象。
import pandas as pd# 创建一个 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35],'City': ['New York', 'Los Angeles', 'Chicago']
}df = pd.DataFrame(data)# 访问单个元素
element = df.loc[0, 'Age']
print("单个元素:")
print(element)
print(type(element))
print()  # 用于添加空行# 选择一列数据
column = df.loc[:, 'Age']
print("一列数据:")
print(column)
print(type(column))
print()# 选择一行数据
row = df.loc[0]
print("一行数据:")
print(row)
print(type(row))
print()# 选择多行多列
subset = df.loc[0:1, ['Name', 'Age']]
print("多行多列:")
print(subset)
print(type(subset))
print()
 输出结果

 


​​​​​​​访问单个元素

import pandas as pd# 创建一个简单的DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35]
}
df = pd.DataFrame(data)# 使用df.loc[0, 'Age']
result_loc = df.loc[0, 'Age']
print("df.loc[0, 'Age']:", result_loc)
print("df.loc[0, 'Age'] 类型:", type(result_loc))# 使用df.at[0,'Age']
result_at = df.at[0, 'Age']
print("df.at[0, 'Age']:", result_at)
print("df.at[0, 'Age'] 类型:", type(result_at))
 输出结果

 df.loc[0, 'Age']: 25
df.loc[0, 'Age'] 类型: <class 'numpy.int64'>
df.at[0, 'Age']: 25
df.at[0, 'Age'] 类型: <class 'numpy.int64'>

df.loc[0, 'Age'] 和 df.at[0, 'Age']   这两个表达式返回的结果是一样的,它们都用于获取DataFrame中第0行(第一行)'Age’列的值。其中 0 是行索引,'Age' 是列名。

不过,两者之间存在一些差异:

性能:df.at[] 比 df.loc[] 更快,因为 df.at[] 专门用于访问单个元素,而 df.loc[] 则更为通用,可以用于选择多行或多列。

灵活性:df.loc[] 更加灵活,可以用于选择多行或多列,也可以用于进行切片等复杂的数据选择。而 df.at[] 只能用于访问单个具体的元素。

在只需要访问单个数据点时,推荐使用 df.at[] 以获得更好的性能;在需要访问多个数据或进行复杂的数据选择时,应使用 df.loc[]。在功能上,如果只是访问单个数据点,两者的结果是相同的。​​​​​​​

.loc 方法可以用于更灵活的数据访问方式,包括选择行和/或列的子集,这时它可能返回 Series 或 DataFrame 对象,具体取决于选择的内容:

访问单个行或列

使用 loc[],你可以通过指定行标签(索引名称)和列标签来访问特定的行或列。

import pandas as pd# 创建一个 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35],'City': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)# 访问单个行
print(df.loc[0])  # 访问索引为0的行# 访问单个列
print(df.loc[:, 'Name'])  # 访问名为'Name'的列

访问多个行或列

你可以通过传递一个列表来访问多个行或列。

# 访问多个行
print(df.loc[[0, 2]]) #  访问第1行和第3行的数据# 访问多个列
print(df.loc[:, ['Name', 'City']])  # 访问'Name'和'City'两列

访问行和列的特定组合

loc[] 同时允许你通过指定行和列的组合来访问数据。

# 访问特定行的特定列
print(df.loc[1, 'Age'])  # 访问索引为1的行的'Age'列# 访问多个行的多个列
print(df.loc[[0, 1], ['Name', 'City']])

条件访问

loc[] 也可以与布尔条件一起使用,使你能够基于列的值来选择行。

# 条件访问
print(df.loc[df['Age'] > 30])  # 访问'Age'大于30的所有行# 条件访问特定列
print(df.loc[df['Age'] > 30, 'Name'])  # 访问'Age'大于30的行的'Name'列

修改 DataFrame 中的数据

loc[] 不仅可以用于访问数据,还可以用于修改数据。你可以指定行列位置来更新 DataFrame 中的数据。

# 修改特定元素
df.loc[0, 'Name'] = 'Ann'  # 将索引为0的行的'Name'修改为'Ann'# 修改一行数据
df.loc[2] = ['Dave', 29, 'Miami']  # 修改索引为2的整行数据# 修改一列数据
df.loc[:, 'City'] = ['City1', 'City2', 'City3']  # 修改整列数据print(df)

通过这些示例,你可以看到 loc[] 的使用是非常灵活的,它可以访问和修改单个值、整行或整列,以及行和列的任意子集。

7. 几种 pandas 数据访问和操作方法

1. 使用 at[]iat[]

at[] 例子

at[] 主要用于访问和修改单个元素。它的优势在于速度,特别是当你需要频繁访问和修改单个元素时。

import pandas as pddata = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35],'City': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)# 修改使用 at[]
df.at[0, 'Name'] = 'Alison'
print("Updated Name:", df.at[0, 'Name'])# 访问使用 at[]
print("Access single element with at[]:", df.at[2, 'City'])

iat[] 例子

at[] 类似,iat[] 用于通过位置访问和修改单个元素,适合已知行列位置的情况。

# 修改使用 iat[]
df.iat[0, 0] = 'Alice'
print("Updated Name:", df.iat[0, 0])# 访问使用 iat[]
print("Access single element with iat[]:", df.iat[2, 2])

2. 使用 query() 方法

query() 方法可以让您使用字符串形式的表达式来查询 DataFrame,这使得代码更易于编写和阅读,特别是在处理复杂条件时。

# 查询年龄大于 30 的行
adults = df.query('Age > 30')
print("Adults:", adults)

3. 布尔索引

布尔索引允许您直接根据条件过滤数据,这是 pandas 中非常直观和强大的数据筛选技术。

# 直接使用布尔条件选择行
over_30 = df[df['Age'] > 30]
print("People over 30:", over_30)# 结合多个条件
over_30_in_ny = df[(df['Age'] > 30) & (df['City'] == 'New York')]
print("People over 30 in NY:", over_30_in_ny)

4. 使用 where()mask()

这两个方法用于基于条件选择数据,where() 在条件为 False 的地方放置 NaN,而 mask() 则在条件为 True 的地方放置 NaN。

# 使用 where,不满足条件的位置将被设置为 NaN
where_filtered = df.where(df['Age'] > 30)
print("Where filtered:", where_filtered)# 使用 mask,满足条件的位置将被设置为 NaN
mask_filtered = df.mask(df['Age'] > 30)
print("Mask filtered:", mask_filtered)

5. 结合修改

使用这些方法不仅可以查询数据,还可以结合修改操作,如更新或改变数据。

# 使用 loc 来增加年龄
df.loc[df['Age'] > 30, 'Age'] += 1
print("Ages incremented for people over 30:", df)# 使用 query 和 loc 修改数据
df.loc[df.query('City == "Chicago"').index, 'City'] = "Chicago - IL"
print("Updated city name for Chicago:", df)

8. query()

使用 query() 方法可以非常方便地处理更复杂的查询条件,并使代码更加清晰。下面我将举例说明如何使用 query() 方法执行各种不同的查询操作,这些示例将涵盖多条件查询、字符串匹配以及使用外部变量等情况。

示例数据集

首先,让我们定义一个包含更多详细信息的示例 DataFrame。

import pandas as pddata = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Ella'],'Age': [25, 30, 35, 40, 22],'City': ['New York', 'Los Angeles', 'Chicago', 'Miami', 'Boston'],'Income': [70000, 85000, 65000, 72000, 80000] #收入
}
df = pd.DataFrame(data)

1. 基础查询

查询年龄大于30岁的成年人:

adults = df.query('Age > 30')
print("Adults over 30:\n", adults)

2. 多条件查询

查询年龄大于 30 并且收入超过 70000 的人:

如果你的查询更加复杂,例如包含多个 andor 条件,确保适当使用括号来组织优先级,避免逻辑错误。

#查询年龄大于 30 并且 收入超过 70000 的人
result = df.query('Age > 30 and Income > 70000')
print("Adults over 30 with income over 70000:\n", result)#查询年龄大于 30 或者 收入超过 70000 的人,你可以使用 or 运算符
result = df.query('Age > 30 or Income > 70000')
print("People over 30 or with income over 70000:\n", result)

3. 字符串操作查询

查询城市名称以 'New' 开头的所有记录:

new_cities = df.query('City.str.startswith("New")', engine='python')
print("People in cities starting with 'New':\n", new_cities)#查询所有在以 "os" 结尾的城市名的记录:
ends_with_os = df.query('City.str.endswith("os")', engine='python')
print("People in cities ending with 'os':\n", ends_with_os)

4. 使用外部变量

假设我们有一个外部变量,我们希望在查询中使用这个年龄阈值:

age_threshold = 25
result = df.query('Age > @age_threshold')
print(f"People older than {age_threshold}:\n", result)

5. 使用索引查询

如果要基于 DataFrame 的索引进行查询,假设索引是一个特定的属性(例如设置'Name'为索引后的查询):

#设置索引,将'Name'列 DataFrame 的设置为索引。这意味着该列的值将被用作行标识符(即索引),而不再是 DataFrame 中的普通列。inplace=True 参数意味着更改将直接在原始 DataFrame 上进行,而不是创建一个新的 DataFrame。
df.set_index('Name', inplace=True)# 使用 query() 方法来查找索引(此处索引是人名)为 "Alice" 的行。这里的 'index' 是一个特殊的关键字,在使用 query() 方法时,它代表 DataFrame 的索引。
result = df.query('index == "Alice"')#这一行代码打印出索引值为 "Alice" 的所有行的信息。如果 "Alice" 是唯一的,那么只会返回一行,包含 Alice 的所有数据(除了 Name,因为它现在是索引)。
print("Data for Alice:\n", result)

6. 组合字符串条件

查询名字包含 'a' 且收入低于 80000 的人:

result = df.query('Name.str.contains("a") and Income < 80000', engine='python')
print("People with 'a' in their names and income less than 80000:\n", result)

9. 索引

在Pandas中,索引(Index)是用来标识数据帧(DataFrame)或者序列(Series)的行的标签。索引是数据处理和分析的关键组件,因为它允许快速访问、定位和修改数据。以下是关于Pandas索引的一些详细信息和重要概念:

1. 索引的类型

Pandas提供了多种类型的索引,每种类型都有其特定的用途和性能特点:

  • RangeIndex:这是最常见的索引类型,类似于Python的range对象。当你创建一个新的DataFrame而没有指定索引时,默认会创建一个从0开始的整数序列。
  • Int64Index:用于存储整数的索引。
  • Float64Index:用于存储浮点数的索引,不常用。
  • DatetimeIndex:特别用于存储日期时间值,非常有用于时间序列数据。
  • PeriodIndex:用于存储周期性数据(例如,具有特定频率的日期范围)。
  • CategoricalIndex:基于类别数据创建的索引,可以提高性能和内存效率。
  • MultiIndex(层次化索引):允许你在一个轴上拥有多个(两个以上)索引级别,非常适合处理高维数据。

2. 设置索引

你可以通过set_index()方法将DataFrame中的一个或多个列转换为索引,也可以在创建DataFrame时通过index参数直接设置。

df.set_index('Column_Name', inplace=True)
# 或在创建时指定
df = pd.DataFrame(data, index=my_index)

在 Pandas 中设置索引列时,虽然你可以将任何列设置为索引,但有一些最佳实践和考虑因素可以帮助你更有效地使用索引,确保数据结构的优化和数据操作的效率。以下是设置索引列时应考虑的几个要点:

1. 唯一性

虽然索引不强制要求必须唯一,但最好使用具有唯一值的列作为索引。唯一的索引值可以提高数据检索的效率,使得每个索引值精确对应一行数据,避免在使用索引访问数据时出现混淆或错误。

2. 不变性

索引列的值最好是不变的。使用不会随时间改变的数据(如用户ID、产品序列号等)作为索引,可以避免因索引变化导致的数据一致性问题。

3. 有意义

索引列应该是有意义的,即它应该对数据分析和操作有实际的帮助。例如,如果你经常需要通过某个特定的字段(如客户ID、时间戳等)来查询数据,那么将这个字段设置为索引会使查询操作更加高效。

4. 数据类型

考虑索引列的数据类型。数值型或日期型的索引通常比字符串型的索引更高效。如果索引列是字符串类型,确保这些字符串不会过长,因为过长的字符串作为索引会增加存储开销并可能影响检索性能。

5. 避免空值

尽量避免在索引列中使用包含空值(NaN)的列。空值在索引中可能导致不预期的行为或错误。

示例

考虑以下数据集,我们将根据上述标准选择合适的索引:

import pandas as pddata = {'CustomerID': [1001, 1002, 1003, 1004],'Name': ['Alice', 'Bob', 'Charlie', 'David'],'Age': [25, 30, 35, 40]
}
df = pd.DataFrame(data)print(df)
print('----------------------------------------')# 设定 CustomerID 为索引
df.set_index('CustomerID', inplace=True)
print(df)

这里,CustomerID 是一个好的索引选择,因为它满足唯一性和不变性的要求,同时对数据操作有实际帮助(如查找特定客户的记录)。

输出结果

 

3. 重置索引

如果你需要将索引列转回数据列,或者想要重置索引为默认的整数索引,可以使用reset_index()方法。

df.reset_index(inplace=True)

4. 索引的操作

索引使得数据的切片和访问非常高效。你可以通过索引标签或位置快速访问数据:

df.set_index('Column_Name', inplace=True)
# 或在创建时指定
df = pd.DataFrame(data, index=my_index)

5. 索引的性能

设置合适的索引可以显著提高数据查询的性能。对于大数据集,建议使用适合数据特性的索引类型(例如,对于时间序列数据使用DatetimeIndex)。

6. 索引的陷阱

  • 修改索引:直接在原索引上修改是不被允许的,因为索引对象是不可变的(Immutable)。如果需要修改索引,你可以替换整个索引或者使用以上的重置方法。
  • 索引的对齐:在进行数据操作时,如两个DataFrame相加,Pandas会根据索引来对齐数据,这可能会导致非预期的结果。因此,明确索引的对齐方式是很重要的。

10.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/11422.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

抱怨无用,行动破局

故事的开始 这个专栏&#xff0c;以及本文的目的&#xff0c;是为了记录我从创立盘多啦这个平台开始&#xff0c;到后续的发展历程的专栏。同时也是给自己一个坚持的动力和警醒的作用。 首先&#xff0c;我是一名程序员&#xff0c;并且对于自身感兴趣的东西&#xff0c;都有…

【仅1月出刊】普刊广涉计算机、社科、教育、法学等多领域!

【欧亚科睿学术】 1 EURASIA JOURNAL OF SCIENCE AND TECHNOLOGY 终审周期 仅1月出刊&#xff08;知网收录&#xff09; 《欧亚科学技术杂志》 Print ISSN&#xff1a;2663-1024 Online ISSN&#xff1a;2663-1016 出版社&#xff1a;UPUBSCIENCE 【简介】本刊致力于传播…

【C语言】指针(一)

目录 一、内存 1.1 ❥ 理解内存和地址的关系 1.2 ❥ 编址 二、指针变量 2.1 ❥ 取地址操作符&#xff08;&&#xff09; 2.2 ❥ 指针变量和解引用操作符&#xff08;*&#xff09; 2.3 ❥ 指针变量的大小 三、指针类型的意义 3.1 ❥ 指针的解引用 3.2 ❥ 指针-整数 3…

PCIE协议-2-事务层规范-TLP Prefix Rules

2.2.10 TLP前缀规则 以下规则适用于任何包含TLP前缀的TLP&#xff1a; 对于任何TLP&#xff0c;TLP中byte0的Fmt[2:0]字段中的值100b表示存在TLP前缀&#xff0c;并且Type[4]位指示TLP前缀的类型。 Type[4]位中的值0b表示存在本地TLP前缀。Type[4]位中的值1b表示存在端到端TL…

R语言数据分析案例-巴西固体燃料排放量预测与分析

1 背景 自18世纪中叶以来&#xff0c;由于快速城市化、人口增长和技术发展&#xff0c;导致一氧化二氮&#xff08;N2O&#xff09;、 甲烷&#xff08;CH4&#xff09;和二氧化碳&#xff08;CO 2&#xff09;等温室气体浓度急剧上升&#xff0c;引发了全球变暖、海平面上 升…

【数据结构】有关栈和队列相互转换问题

文章目录 用队列实现栈思路实现 用栈实现队列思路实现 用队列实现栈 Leetcode-225 用队列实现栈 思路 建立队列的基本结构并实现队列的基本操作 这部分这里就不多说了&#xff0c;需要的可以看笔者的另一篇博客 【数据结构】队列详解(Queue) 就简单带过一下需要实现的功能 …

信息量、熵、KL散度、交叉熵概念理解

信息量、熵、KL散度、交叉熵概念理解 (1) 信息量 信息量是对事件的不确定性的度量。 假设我们听到了两件事&#xff0c;分别如下&#xff1a;事件A&#xff1a;巴西队进入了世界杯决赛圈。 事件B&#xff1a;中国队进入了世界杯决赛圈。仅凭直觉来说&#xff0c;显而易见事件…

Python从0到POC编写-魔法方法

name __name__ 是系统定义的内部函数&#xff0c; 它的作用是识别模块。 通常我们看到这样一句话&#xff1a; if __name__ __main____name__ 的值有两种情况&#xff0c;那么挨个来说下。 如果模块是被直接执行的 &#xff0c;那么 __name__ 的值 为 __main__ 例如&…

html中用frameset对窗口进行划分

html中&#xff0c;一般有<head><body>等部分&#xff0c;在用<frameset>对窗口进行区域划分时&#xff0c;<body>标签对就不再需要了。直接删除就可以了。 请看下面的示例&#xff1a; 由于使用frameset进行窗口划分时&#xff0c;对于电脑屏幕的划分…

排序-快速排序(Quick Sort)

快排的简介 快速排序&#xff08;Quick Sort&#xff09;是一种高效的排序算法&#xff0c;采用分治法的策略&#xff0c;其基本思想是选择一个基准元素&#xff0c;通过一趟排序将待排序的数据分割成独立的两部分&#xff0c;其中一部分的所有数据都比另外一部分的所有数据要…

Android 老年模式功能 放大字体

1 配置属性 <attr name"text_size_16" format"dimension"/><attr name"text_size_18" format"dimension"/><attr name"text_size_14" format"dimension"/><attr name"text_size_12&quo…

容器组件:Column ,Row(HarmonyOS学习第四课【4.1】)

容器组件-Column Column 容器组件是沿垂直方向布局的容器。该组件从APIVersion7开始支持从API version 9开始&#xff0c;该接口支持在ArkTs,卡片中使用。其可以包含子组件 Column(value?: {space?: string | number}) 参数 space 参数类型string | number 是否必填&am…

第11节 多文件函数生成位置规律

我把多年的shellcode开发经验浓缩在了这个专题课&#x1f469;&#x1f3fb;‍&#x1f4bb;里&#xff0c;主要面向对网络安全技术感兴趣的小伙伴。这是视频版内容对应的文字版材料&#xff0c;内容里面的每一个环境我都亲自测试实操过的记录&#xff0c;有需要的小伙伴可以参…

进程创建-fork

demo1代码状态变迁 demo2代码输出到stdout使用管道 demo1 代码 #include <pthread.h> #include <iostream> #include <unistd.h> int main(int argc, char const *argv[]) {// 1.pid_t x fork();// 2.pid_t y fork();// 3.printf("%d %d\n", x…

【C++】STL-list的使用

目录 1、list的使用 1.1 list的构造 1.2 list的遍历 1.3 list capacity 1.4 list element access 1.5 容量相关 list是一个带头双向循环链表 1、list的使用 1.1 list的构造 1.2 list的遍历 list只有两种遍历方式&#xff0c;因为没有operator[] 因为list的双向链表&am…

《建筑抗震设计规程》DB62/T 3055-2020下载

本规程适用于抗震设防分类为乙类、丙类&#xff0c;抗震设防烈度为6度(0.05g)、7度(0.10g、0.15g)、8度(020g、030g)、9度(0.40g)的多高层钢筋混凝土结构及钢-混凝土混合结构、中等跨度钢屋盖结构、门式刚架钢结构、多低层砖砌体结构房屋建筑的抗震设计。 关于甘肃省地方标准《…

01 | 为什么需要消息队列?

哪些问题适合使用消息队列来解决&#xff1f; 1. 异步处理 2. 流量控制 使用消息队列隔离网关和后端服务&#xff0c;以达到流量控制和保护后端服务的目的。 3. 服务解耦 无论增加、减少下游系统或是下游系统需求如何变化&#xff0c;订单服务都无需做任何更改&#xff0c…

【主题广泛|稳定检索】2024年社会科学、公共服务与人文艺术国际会议(SPSHA 2024)

2024年社会科学、公共服务与人文艺术国际会议&#xff08;SPSHA 2024&#xff09; 2024 International Conference on Social Sciences, Public Services, and Humanities and Arts 【会议简介】 本次会议定于2024年在中国的繁华都市——广州召开&#xff0c;汇聚了全球在该领…

如何挑选护眼灯?分享最好的台灯品牌排行榜

作为家长&#xff0c;孩子的健康无疑是我们最为牵挂的事项。然而&#xff0c;通过研究数据显示&#xff0c;我国青少年儿童的近视率高达52.7%&#xff0c;这意味着在每十名儿童中&#xff0c;就有超过半数的孩子可能面临视力问题。这一数据无疑令人警觉。当我们看到孩子们在写作…

Web3加密空投入门:空投类型有哪些?如何避免限制?

今天分享空投如何避免限制以提高效率&#xff0c;增加成功几率&#xff0c;首先我们来了解什么是空投加密&#xff0c;有哪些空投类型。 一、什么是空投加密&#xff1f; 加密货币空投是一种营销策略&#xff0c;包括向用户的钱包地址发送免费的硬币或代币。 加密货币项目使用…