【发布时间】:2019-10-22 10:01:29
【问题描述】:
我的任务是找出中心元素可变距离内所有元素的总值。元素使用 3 个维度(我的数据中的列)排列。每个元素都有一个给定 3 个维度的唯一位置(并且有一个唯一 ID)。
我有一个可以满足我要求的工作版本,但是速度非常慢。我正在使用 itertuples,使用子集数据框 apply(np.isclose) 查找每个元组的值,然后使用 .at 设置值(请参见下面的代码)。
问题不在于我的代码的功能,而在于可扩展性。由于我想设置一个可变距离来测量,并且我想为每一行计算这个值,它最终迭代 nrows x ndistances,目前每次迭代需要 1.7 秒(我的数据有 >25,000 行,我估计 ~12 小时我尝试的每一个距离)。
import pandas as pd
import numpy as np
数据结构示例:
df = pd.DataFrame({'id':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],
'x':[-2,-2,-2,-1,-1,-1,-1,0,0,0,0,0,1,1,1,1,2,2,2],
'y':[2,1,0,2,1,0,-1,2,1,0,-1,-2,1,0,-1,-2,0,-1,-2],
'z':[0,1,2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,-2,-1,0],
'val':[0,0,0,1,0,0,6,3,7,11,0,0,14,18,10,4,20,15,2]})
df.set_index('id', inplace=True)
# The 'val' column can have any non-negative whole number, I've just picked some randomly.
到目前为止的“工作”代码:
n = 0 #Initial distance
while n < 3: #This part allows me to set my distance range
df['n{0}'.format(n)] = np.nan #create a column for the new values
for row in df.itertuples():
valsum = df[(df['x'].apply(np.isclose, b=row.x, atol=n)) &
(df['y'].apply(np.isclose, b=row.y, atol=n)) &
(df['z'].apply(np.isclose, b=row.z, atol=n))].val.sum()
df.at[row.Index, 'n{0}'.format(n)] = valsum
n += 1
当前/期望的输出:
x y z val n0 n1 n2
id
1 -2 2 0 0 0 1 22
2 -2 1 1 0 0 0 25
3 -2 0 2 0 0 6 17
4 -1 2 -1 1 1 11 54
5 -1 1 0 0 0 19 70
6 -1 0 1 0 0 17 57
7 -1 -1 2 6 6 6 31
8 0 2 -2 3 3 25 74
9 0 1 -1 7 7 54 99
10 0 0 0 11 11 46 111
11 0 -1 1 0 0 31 73
12 0 -2 2 0 0 10 33
13 1 1 -2 14 14 62 99
14 1 0 -1 18 18 95 105
15 1 -1 0 10 10 60 107
16 1 -2 1 4 4 16 66
17 2 0 -2 20 20 67 100
18 2 -1 -1 15 15 65 101
19 2 -2 0 2 2 31 80
我知道“n0”列等于“val”列,因为搜索距离为 0,但我希望显示我正在寻找的内容。 val列中所有项的总和为111,当(x,y,z) = (0,0,0)时相同。这是因为 (0,0,0) 是本示例中我的数据的中心,因此距离为 2 会捕获所有元素。我想在一定距离的带宽内执行此操作,例如 5-10。
我的终极问题是:我怎样才能更快/更有效地做到这一点?
【问题讨论】:
-
您的
n+= 1需要退出 for 循环,否则您将无法获得当前答案。 -
您的距离标准定义了曼哈顿距离,而不是欧几里得(直线)距离。这是故意的吗?
-
@Ben Pap 你是对的,我会解决的。在我的文件中是正确的
-
@zoupah,明白了,谢谢!也许我可以以一种可以轻松适应任一距离度量的方式回答。
-
道歉:我错误地写了问题中的逻辑描述了曼哈顿距离,而实际上它定义了切比雪夫距离 (en.wikipedia.org/wiki/Chebyshev_distance)。对不起,如果这误导了任何人走错了路。
标签: python arrays pandas numpy