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 pd

data = {
    '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 pd

data = {
    '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 pd

data = {
    '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.

  • 31
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python Pandas是一种快速、强大、灵活且易于使用的开源数据分析和数据操作工具,它可以帮助我们进行数据清洗、数据分析、数据可视化等操作。下面是Python Pandas对Excel操作的步骤: 1. 安装Pandas库 可以使用pip install pandas来安装Pandas库。 2. 导入Excel文件 可以使用pandas.read_excel()函数来导入Excel文件,该函数的参数包括文件路径、sheet名称、开始行、结束行等。 ```python import pandas as pd df = pd.read_excel('data.xlsx', sheet_name='Sheet1', header=0) ``` 3. 数据清洗 可以使用Pandas库提供的各种函数来对数据进行清洗,例如删除重复行、替换空值、删除列等。 ```python df.drop_duplicates() # 删除重复行 df.fillna(0) # 将空值替换为0 df.drop(columns=['column1', 'column2']) # 删除指定列 ``` 4. 数据分析 可以使用Pandas库提供的函数来对数据进行分析,例如统计每列的平均值、方差、标准差等。 ```python df.mean() # 每列的平均值 df.var() # 每列的方差 df.std() # 每列的标准差 ``` 5. 数据可视化 可以使用Pandas库提供的函数来对数据进行可视化,例如绘制折线图、柱状图、饼图等。 ```python df.plot(kind='line', x='date', y='value') # 绘制折线图 df.plot(kind='bar', x='category', y='value') # 绘制柱状图 df.plot(kind='pie', x='category', y='value') # 绘制饼图 ``` 6. 导出Excel文件 可以使用Pandas库提供的函数将数据导出为Excel文件,例如将清洗后的数据导出为新的Excel文件。 ```python df.to_excel('clean_data.xlsx', index=False) # 导出Excel文件 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值