pandas - 高效的数据框查找和提取
问题描述
我想通过 8 个坐标的 x,y,z 平均值计算质心。元素 ID 指的是立方体,而节点 ID 指的是立方体上的球体。我有一个数据框,其中包含元素 ID 和连接节点上的 ID。在另一个数据框中,我有节点 ID 及其坐标。为每个元素 ID 查找相邻节点坐标并基于这些计算立方体质心的最有效方法是什么?
包含元素 ID 和节点 ID 的 Dataframe 的数据结构
Element ID Node 1 Node 2 Node 3 ... Node 5 Node 6 Node 7 Node 8
0 856395 764524 768124 767621 ... 766463 768139 767613 767612
1 856396 764524 767551 767621 ... 764525 767491 767622 768125
2 856397 764525 767491 767622 ... 764526 767431 767623 768126
3 856398 764526 767431 767623 ... 764527 767371 767624 768127
4 856399 764527 767371 767624 ... 764528 767311 767625 768128
包含节点 ID 和节点坐标的 Dataframe 的数据结构
Node ID X Y Z
0 764525 0.342972 -0.104031 6.499699
1 764526 0.342976 -0.104033 6.514697
2 764527 0.342979 -0.104034 6.529694
3 764528 0.342980 -0.104034 6.544691
4 764529 0.342981 -0.104035 6.559689
这可行,但真的很丑而且很慢:-(
append1 = pd.merge(df_element_ids_nodes,df_node_ids_coordinates, left_on="Node 1", right_on="Node ID")
append2 = pd.merge(append1,df_node_ids_coordinates, left_on="Node 2", right_on="Node ID")
append3 = pd.merge(append2,df_node_ids_coordinates, left_on="Node 3", right_on="Node ID")
append4 = pd.merge(append3,df_node_ids_coordinates, left_on="Node 4", right_on="Node ID")
append5 = pd.merge(append4,df_node_ids_coordinates, left_on="Node 5", right_on="Node ID")
append6 = pd.merge(append5,df_node_ids_coordinates, left_on="Node 6", right_on="Node ID")
append7 = pd.merge(append6,df_node_ids_coordinates, left_on="Node 7", right_on="Node ID")
append8 = pd.merge(append7,df_node_ids_coordinates, left_on="Node 8", right_on="Node ID")
print(append8)
df_results = pd.DataFrame(columns=["ElementId", "X", "Y", "Z"])
for index, row in append8.iterrows():
centroid_x = (row[10] + row[14] + row[18] + row[22] + row[26] + row[30] + row[34] + row[38])/8
centroid_y = (row[11] + row[15] + row[19] + row[23] + row[27] + row[31] + row[35] + row[39])/8
centroid_z = (row[12] + row[16] + row[20] + row[24] + row[28] + row[32] + row[36] + row[40])/8
Element_ID = row[0]
df_results = df_results.append({"ElementId": int(Element_ID), "X": centroid_x, "Y": centroid_y, "Z": centroid_z}, ignore_index=True)
print(df_results)
解决方案
一种非常有效的方法是执行数据帧的数据帧连接。连接应该对 ID 进行排序,并对包含出现在主数据框中的每个所需 ID 的节点 ID 的数据帧的 ID 执行二分法。这个操作是O(n log n)
及时完成的。在最好的情况下,它可以散列节点索引以及O(1)
时完成。这里有两个例子:
# Case 1 -- discard the 'Node ID' field:
elementDataframe.set_index('Node ID').join(nodeDataframe.set_index('Node ID'))
# Case 2 -- do not discard the field and is simpler to use:
elementDataframe.merge(nodeDataframe, on='Node ID')
如果节点 ID 是连续的(并且如此排序),那么有一个更快的解决方案:您可以使用直接访问(如查找表)获取节点 ID,在您的示例中使用nodeDataframe.iloc[nodeIndices-startingId]
where startingId
is 764525 并且nodeIndices
是一个包含节点 ID(例如。elementDataframe['Node 1']
此操作O(n)
及时完成,应该比基本连接更快。更准确地说,在您的情况下,代码应如下所示:
nodeDataframe.iloc[elementDataframe['Node ID']-nodeDataframe['Node ID'].min()]
推荐阅读
- powershell - 如何使用 Powershell 将十六进制字符串转换为 bin?
- javascript - 如何在 QML 中使用 TableView 从 QtQuickControls 1 获取列数据?
- react-native - 选择值时反应材质UI关闭 - 多选
- php - 如何将 2 个 json 数据与具有不同键但相同值的 php 结合起来
- mysql - 为每个人选择最早的记录
- python-3.x - 如何从 Python 中的文字字节创建图像?
- json - 如何使用 Spark Scala 从 JSON 文件为字段子集创建模式?
- javascript - 在具有复杂条件的两个对象数组之间检索项目
- java - 更新到 SpringBoot 2.4.0 后内存数据库中的 H2 无法正常工作
- python - 我在 djangorest profile_data = valid_data.pop('profile') KeyError: 'profile' 中有一个问题