
本文详细介绍了如何根据一个索引列表,从现有pandas dataframe中高效提取对应的x、y坐标,并构建一个新的dataframe。文章首先探讨了基于循环和字典的初步实现方式及其改进,随后重点展示了利用numpy进行矢量化操作的优化方案,该方案显著提升了数据处理性能,为后续的数据可视化和分析奠定了坚实基础。
在数据处理和分析中,我们经常需要根据特定的映射规则从一个数据集中提取信息并重构为新的数据结构。本教程将聚焦于一个常见场景:给定一个包含索引对的列表和一个包含坐标信息的Pandas DataFrame,目标是创建一个新的DataFrame,其中每一行代表一个由索引对指向的X、Y坐标。
假设我们拥有以下两组数据:
我们的任务是创建一个名为 coord 的新DataFrame,它只有 X 和 Y 两列。coord 的每一行都应根据 tours 中的索引对,从 df 中查找对应的X和Y值。
示例原始数据:
import pandas as pd
import numpy as np
tours = [[0, 4], [0, 5], [0, 6], [1, 13], [2, 0], [3, 8], [4, 9], [5, 10],
[6, 7], [7, 1], [8, 2], [9, 3], [10, 11], [11, 14], [12, 0], [13, 12], [14, 0]]
data = {
'Node': [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
'X': [5.7735, 2.8867, -2.8868, -5.7735, -2.8867, 2.8868, 8.6603, 0.0000, -8.6603, -8.6603, 0.0000, 8.6603, 5.3405, 3.3198, 6.4952],
'Y': [0.00, 5.00, 5.00, 0.00, -5.00, -5.00, 5.00, 10.00, 5.00, -5.00, -10.00, -5.00, 0.75, 4.25, -1.25],
'Demand': [40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 10.0, 10.0, 10.0],
'Profit': [16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 24.0, 24.0, 24.0, 24.0, 24.0, 10.0, 10.0, 11.0]
}
df = pd.DataFrame(data, index=range(len(data['Node']))) # 确保df的索引从0开始,与tours中的索引匹配理解 tours 的含义:tours 中的 [0, 4] 表示:
一种直观的方法是遍历 tours 列表,在每次迭代中根据索引从 df 中提取X和Y值,并将它们存储在一个字典中,最后将字典转换为DataFrame。
最初的尝试可能如下:
d = {}
for t, tour in enumerate(tours):
xi = tour[0]
yi = tour[1]
key = t
d[key] = df["X"].iloc[xi], df["Y"].iloc[yi]
# 尝试直接使用pd.DataFrame(d.items(), columns=['X', 'Y'])
# 这将导致错误或不符合预期的结果,因为d.items()会把键作为第一列,值(元组)作为第二列这种方法在将字典 d 转换为DataFrame时会遇到问题。pd.DataFrame(d.items(), columns=['X', 'Y']) 会将字典的键作为第一列(在这里是索引 0, 1, 2...),而将值(一个包含X和Y的元组)作为第二列。这并不是我们期望的两列 X 和 Y。
为了正确地将字典转换为DataFrame,其中字典的键作为DataFrame的索引,而字典的值(元组)拆分为多列,我们需要使用 pd.DataFrame.from_dict() 方法,并设置 orient='index' 参数。
d = {}
for t, tour in enumerate(tours):
xi = tour[0] # 获取X坐标的索引
yi = tour[1] # 获取Y坐标的索引
# 根据索引从df中查找对应的X和Y值
x_val = df["X"].iloc[xi]
y_val = df["Y"].iloc[yi]
d[t] = (x_val, y_val) # 将(X, Y)元组作为字典的值
# 使用from_dict并指定orient='index'来正确构建DataFrame
coord_loop = pd.DataFrame.from_dict(d, orient='index', columns=['X', 'Y'])
print("方法一(循环+字典)结果:")
print(coord_loop.head())优点:
缺点:
对于Pandas和NumPy而言,矢量化操作通常比Python循环具有更高的性能。我们可以将 tours 转换为NumPy数组,并将 df 中的X、Y列提取为NumPy数组,然后利用NumPy的高级索引功能一步到位地获取所有坐标。
# 1. 将tours列表转换为NumPy数组
tours_np = np.array(tours)
# 2. 从df中提取X和Y列,并转换为NumPy数组
# 这样arr[index, 0] 对应X值,arr[index, 1] 对应Y值
df_coords_np = df[["X", "Y"]].to_numpy()
# 3. 使用高级索引一次性获取所有X和Y坐标
# tours_np[:, 0] 提供了所有X坐标的索引
# tours_np[:, 1] 提供了所有Y坐标的索引
extracted_x = df_coords_np[tours_np[:, 0], 0] # 获取所有X坐标
extracted_y = df_coords_np[tours_np[:, 1], 1] # 获取所有Y坐标
# 4. 构建最终的DataFrame
coord_vectorized = pd.DataFrame({"X": extracted_x, "Y": extracted_y})
print("\n方法二(NumPy矢量化)结果:")
print(coord_vectorized.head())代码解释:
优点:
在处理中小型数据集时,两种方法可能在执行时间上差异不大。然而,当 tours 列表包含成千上万甚至数百万个元素时,NumPy的矢量化方法将展现出压倒性的性能优势。
最佳实践建议:
本教程展示了两种从索引映射构建坐标DataFrame的方法。虽然基于循环和字典的方法直观易懂,但利用NumPy进行矢量化处理是更高效、更专业的解决方案,尤其适用于大规模数据处理。
最终生成的 coord DataFrame(无论是通过方法一的改进版还是方法二)都包含了我们需要的X和Y坐标对。这个DataFrame可以直接用于后续的数据可视化任务,例如使用Matplotlib、Seaborn或Plotly等库绘制路径或散点图。例如,要绘制路径,可以直接使用 coord['X'] 和 coord['Y'] 作为绘图函数的输入。
# 示例:使用matplotlib绘制路径(需要安装matplotlib)
# import matplotlib.pyplot as plt
# plt.figure(figsize=(10, 8))
# plt.plot(coord_vectorized['X'], coord_vectorized['Y'], marker='o', linestyle='-', color='blue')
# plt.title('Generated Route Coordinates')
# plt.xlabel('X Coordinate')
# plt.ylabel('Y Coordinate')
# plt.grid(True)
# plt.show()掌握这种高效的数据提取和重构技术,将极大地提升您在Python数据科学项目中的工作效率。
以上就是利用Pandas和NumPy高效从索引映射生成坐标DataFrame的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号