Python 如何在字典中过滤一行,计算范围,并从中找到在该范围内的类似行?
如何使用多处理过滤一行,计算范围,并在字典中查找属于该范围的类似行,其中id作为键,id作为值属于该范围 假设我有一个数据帧:Python 如何在字典中过滤一行,计算范围,并从中找到在该范围内的类似行?,python,python-3.x,pandas,dataframe,parallel-processing,Python,Python 3.x,Pandas,Dataframe,Parallel Processing,如何使用多处理过滤一行,计算范围,并在字典中查找属于该范围的类似行,其中id作为键,id作为值属于该范围 假设我有一个数据帧: id val1 val2 1 10 20 2 9.5 19 3 100 200 4 9.3 19.2 5 96 196 6 99 198 7 103 202 8 140 280 对于每个id i,我将计算: upper_val1 = df[df.id==i].v
id val1 val2
1 10 20
2 9.5 19
3 100 200
4 9.3 19.2
5 96 196
6 99 198
7 103 202
8 140 280
对于每个id i,我将计算:upper_val1 = df[df.id==i].val1 * (1+0.1)
lower_val1 = df[df.id==i].val1 * (1-0.1)
upper_val2 = df[df.id==i].val2 * (1+0.1)
lower_val2 = df[df.id==i].val2 * (1-0.1)
子集df:
sub_df = df[(df.val1<=upper_val1)&df.val1>=lower_val1)&(df.val1<=upper_val2)&df.val1>=lower_val2)
我有一个包含数百万条记录的数据帧,这一步骤应该对每一行重复,因此如何使用多处理来完成这一步骤?为了实现这一点,我们将在数据帧上应用一个函数,计算值位于数据帧行范围内的ID
df = pd.DataFrame.from_records([
{'id': 1, 'val1': 10.0, 'val2': 20.0},
{'id': 2, 'val1': 9.5, 'val2': 19.0},
{'id': 3, 'val1': 100.0, 'val2': 200.0},
{'id': 4, 'val1': 9.3, 'val2': 19.2},
{'id': 5, 'val1': 96.0, 'val2': 196.0},
{'id': 6, 'val1': 99.0, 'val2': 198.0},
{'id': 7, 'val1': 103.0, 'val2': 202.0},
{'id': 8, 'val1': 140.0, 'val2': 280.0}]
)
def rows_in_range(row):
index = row.name
val1 = row['val1']
val2 = row['val2']
return (df['val1'].between(val1*(1-.1), val1*(1+.1)) &
df['val2'].between(val2*(1-.1), val2*(1+.1)) &
(df.index != index)
)
# row.name gives the index value for that row
ids = df.apply(
lambda row: df.loc[rows_in_range(row), 'id'].tolist(),
axis=1,
result_type='reduce'
)
indices
0 [2, 4]
1 [1, 4]
2 [5, 6, 7]
3 [1, 2]
4 [3, 6, 7]
5 [3, 5, 7]
6 [3, 5, 6]
7 []
dtype: object
现在我们要做的就是把它的索引转换成ID
indices.index = df.loc[indices.index, 'id']
indices.to_dict()
{1: [2, 4],
2: [1, 4],
3: [5, 6, 7],
4: [1, 2],
5: [3, 6, 7],
6: [3, 5, 7],
7: [3, 5, 6],
8: []}
我很好奇这对于数百万行来说是否足够,但至少它是正确的。我本想建议自合并,但后来我看到了数百万行,我放弃了。您现在看到的是
10**12
成对比较。如果可以使用numpy数组而不是pandas,您可能有一个解决方法。Cupy基本上是为NVIDIA图形卡上的CUDA内核制作的numpy。我已经看到矩阵数学中使用这种方法的速度提高了几个数量级,因为图形卡可以有数百或数千个内核。这实际上取决于是否可以在CPU缓存上执行数学运算,或者需要更多运算。@Jake你能分享一个示例代码吗?这里应该计算val1和val2的范围,并且id是not列中的一个index@ShadabHussain我更新了我的答案,将val1
和val2
都考虑在内。我的答案正确地使用了id
;它只使用索引来查找正确的id
s。是的,从逻辑上讲,这对于较小的数据帧很好,但是当您有数百万条记录时,性能是问题之一。我正在寻找如何克服这个性能问题
indices.index = df.loc[indices.index, 'id']
indices.to_dict()
{1: [2, 4],
2: [1, 4],
3: [5, 6, 7],
4: [1, 2],
5: [3, 6, 7],
6: [3, 5, 7],
7: [3, 5, 6],
8: []}