【问题标题】:Most efficient method to loop through a dataframe and return a filtered array of values based on multiple criteria循环遍历数据框并返回基于多个条件的过滤值数组的最有效方法
【发布时间】:2021-01-08 07:26:45
【问题描述】:

我有一个数据集,其中包含事件数据,包括各种元素以及这些元素在不同时间点的位置数据。整个数据集非常庞大,涵盖了许多此类事件。

对于每个时间点的每个元素,我想找到最接近的其他元素。首先,我将返回一个包含所有其他元素在特定时间段内的位置数据的数组,并将其包含在原始数据帧的同一行中(以便稍后执行进一步的计算)。

我有两次尝试对此进行编码,我已将其包括在下面。在如此庞大的数据集上,两者都花费了太长时间。任何能让我提高效率的方法都将不胜感激。

import pandas as pd
import numpy as np

def func1(db, val, frame):
  return db.loc[(db['val'].isin([val])) & (db['frameId'].isin([frame])) & ['displayName', 'x', 'y']] 
  .reset_index(drop=True).values.tolist()

d = pd.DataFrame({'displayName': ['Bob', 'Jane', 'Alice',  
                'Bob', 'Jane', 'Alice'], 
                'x': [90, 88, 86, 94, 91, 92], 
                'y': [24, 13, 18, 20, 15, 16], 
                'val': [201801, 201801, 201801, 201801, 201801, 201801], 
                'frameId': [1, 1, 1, 2, 2, 2]})

res = d.apply(lambda row: func1(d, row['val'], row['frameId']), axis=1)

方法二:

def func2(db, val, frame):
   return [l[[0, 1, 2]] for l in db if l[3] == val if l[4] == frame]

res = d.apply(lambda row: func2(np.array(d), row['val'], row['frameId']), axis=1)  

因此,结果 (res) 将是一个如下所示的数组:

[[['Bob', 90, 24], ['Jane', 88, 13], ['Alice', 86, 18]],
 [['Bob', 90, 24], ['Jane', 88, 13], ['Alice', 86, 18]],
 [['Bob', 90, 24], ['Jane', 88, 13], ['Alice', 86, 18]],
 [['Bob', 94, 20], ['Jane', 91, 15], ['Alice', 92, 16]],
 [['Bob', 94, 20], ['Jane', 91, 15], ['Alice', 92, 16]],
 [['Bob', 94, 20], ['Jane', 91, 15], ['Alice', 92, 16]]]

但是在大​​型数据集上,这两种方法都非常耗时,因此欢迎任何降低时间复杂度的方法。

【问题讨论】:

  • 请在此处查看如何创建pandas 最小可重现示例:stackoverflow.com/questions/20109391/…。您需要输入数据和输出数据(无图像)。输入数据可以只是问题的一个小样本数据集。
  • 谢谢你。现在已经更新了原来的问题。
  • 现在几乎包含了您的预期输出,因此回答者可以知道他们是否提供了正确的解决方案。
  • 好的,又更新了。

标签: pandas numpy optimization coding-efficiency


【解决方案1】:

如果3D-Array 的第一个维度的顺序不重要,请使用(如果重要,那么您将必须创建一个按displayNameindex 分组的系列并采用@ 987654324@。按此排序然后丢弃。让我知道。:

import pandas as pd
import numpy as np
d = pd.DataFrame({'displayName': ['Bob', 'Jane', 'Alice',  
                'Bob', 'Jane', 'Alice'], 
                'x': [90, 88, 86, 94, 91, 92], 
                'y': [24, 13, 18, 20, 15, 16], 
                'val': [201801, 201801, 201801, 201801, 201801, 201801], 
                'frameId': [1, 1, 1, 2, 2, 2]})
n = d['frameId'].max() + 1
x = d['displayName'].nunique()
pd.concat([d.iloc[:,0:3]]*n).to_numpy().reshape(df.shape[0],x,x)
Out[1]: 
array([[['Bob', 90, 24],
        ['Jane', 88, 13],
        ['Alice', 86, 18]],

       [['Bob', 94, 20],
        ['Jane', 91, 15],
        ['Alice', 92, 16]],

       [['Bob', 90, 24],
        ['Jane', 88, 13],
        ['Alice', 86, 18]],

       [['Bob', 94, 20],
        ['Jane', 91, 15],
        ['Alice', 92, 16]],

       [['Bob', 90, 24],
        ['Jane', 88, 13],
        ['Alice', 86, 18]],

       [['Bob', 94, 20],
        ['Jane', 91, 15],
        ['Alice', 92, 16]]], dtype=object)

【讨论】:

  • 这是个好主意,但是我需要根据多个条件进行过滤。例如,我需要根据每个“frameId”(只是时间的度量)的“val”(就像一个关键标识符)获取每个人的 x,y 坐标数组,然后确定例如,在每个时间点,谁是最接近 Bob 的人。我只是看到,通过我尝试过的所有方法(包括尝试应用矢量化技术),脚本的运行时间都非常长。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 2012-03-10
  • 1970-01-01
  • 2019-10-22
  • 2014-11-17
  • 2019-03-23
  • 2020-01-06
相关资源
最近更新 更多