Python Pandas-for循环并查找具有最近值的索引

Python Pandas-for循环并查找具有最近值的索引,python,pandas,Python,Pandas,我基本上是在尝试循环一个已分组的数据帧,并找到与输入参数值最接近的索引 例如,给定下面的数据帧,对于由global\u id定义的每个组,我希望分组以获取间隔至少为10帧的帧。例如,如果我有一个帧列表[1,2,3,4,14,20,30,31],那么输出将是[1,14,30],因为 我将以帧1作为第一帧进行初始化 至少相隔10帧的下一帧将是帧编号14 与14相距至少10帧的下一帧为30帧 因此,产生的前后数据帧应如下所示 以前 后过滤器 下面是我所拥有的。一旦我有了索引,我就可以通过从旧数据框

我基本上是在尝试循环一个已分组的数据帧,并找到与输入参数值最接近的索引

例如,给定下面的数据帧,对于由
global\u id
定义的每个组,我希望分组以获取间隔至少为10帧的帧。例如,如果我有一个帧列表[1,2,3,4,14,20,30,31],那么输出将是[1,14,30],因为

  • 我将以帧1作为第一帧进行初始化
  • 至少相隔10帧的下一帧将是帧编号14
  • 与14相距至少10帧的下一帧为30帧
因此,产生的前后数据帧应如下所示

以前

后过滤器

下面是我所拥有的。一旦我有了索引,我就可以通过从旧数据框建立索引来创建一个新的数据框。我对熊猫还是新手,它看起来非常笨重,所以我希望有一个更优雅的解决方案。我已经阅读了groupby和其他一些SO帖子上的文档,但仍然无法理解。这不是家庭作业。我只是想用熊猫来代替所有的东西来清理我的数据处理管道

ind = []
for j in df["global_id"].unique():
    df_temp = df[df["global_id"] == j][["frame_no"]]
    df_temp["frame_no"] = pd.to_numeric(df["frame_no"]) 
    start_frame = df_temp["frame_no"].min()
    end_frame = df_temp["frame_no"].max()
    i = start_frame-1
    while i < end_frame:
        ind.append(np.min(df_temp[(df_temp["frame_no"] > i) & (df_temp["frame_no"] < i+10)].index.tolist()))
        i+=10
ind=[]
对于df[“全局_id”]中的j。唯一()
df_temp=df[df[“全局_id”]==j][[“帧号”]]
df_temp[“帧号”]=局部放电到数字(df[“帧号”])
开始帧=df帧温度[“帧号”].min()
end_frame=df_temp[“frame_no”].max()
i=开始_帧-1
当ii)和(df_temp[“frame_no”]
这里有一种使用
groupby
的方法,但首先需要定义一个函数,在每个组中执行所需的操作。为了解释这个想法,让我们考虑一个简单的数据文件<代码> DFS=PD。DataFrame({ A):[1,2,3,4,14,20,30,31:})< /代码>

我一直在寻找解决这类问题的方法,试图避免循环,这似乎很复杂。这是我最后的想法。在numpy中,您可以使用
substract
outer
组合,以一对一地获得每个元素之间的所有差异

print (np.subtract.outer(dfs.a, dfs.a))
array([[  0,  -1,  -2,  -3, -13, -19, -29, -30],
       [  1,   0,  -1,  -2, -12, -18, -28, -29],
       [  2,   1,   0,  -1, -11, -17, -27, -28],
       [  3,   2,   1,   0, -10, -16, -26, -27],
       [ 13,  12,  11,  10,   0,  -6, -16, -17],
       [ 19,  18,  17,  16,   6,   0, -10, -11],
       [ 29,  28,  27,  26,  16,  10,   0,  -1],
       [ 30,  29,  28,  27,  17,  11,   1,   0]], dtype=int64)
现在,例如,在
列0
中,您可以看到差异
>10
行4
开始,然后到
列4
,差异
>10
行6
开始,到
列6
您没有得到足够大的差异。因此,过滤将保留第0、4和6行,这是要查找的值[1,14,30]。要获得这些数字,您可以将
np.substract.outer
sum
轴=0上进行比较,例如:

arr = (np.subtract.outer(dfs.a, dfs.a) <=10).sum(0)
print (arr)
array([4, 4, 4, 5, 6, 7, 8, 8])
现在,对于整个问题和
groupby
,您可以执行以下操作:

# it seems you need to convert the column frame_no to integer
df['frame_int'] = pd.to_numeric(df['frame_no'])
df = df.sort_values('frame_int') #ensure data to be sorted by frame_int, whatever the global_id

#define the function looking for the ind
def find_ind (df_g):
    list_ind = [0]
    arr = (np.subtract.outer(df_g.frame_int, df_g.frame_int) <= 10).sum(0)
    i = arr[0]
    while i <len(arr):
        list_ind.append(i)
        i = arr[i]
    return df_g.iloc[list_ind]

#create the filtered dataframe
df_filtered = (df.groupby('global_id').apply(find_ind)
                 .drop('frame_int',axis=1).reset_index(drop=True))

print (df_filtered)
   seq_name     label  pedestrian_id  frame_no  global_id
0         1  crossing              1         1          1
1         1  crossing              2         1          2
2         1  crossing              2        12          2
3         1  crossing              2        29          2
4         2  crossing              1        34          3
5         2  crossing              1        49          3
#似乎需要将列帧号转换为整数
df['frame\u int']=pd.to\u numeric(df['frame\u no'])
df=df.sort_值('frame_int')#确保数据按frame_int排序,无论全局_id如何
#定义查找ind的函数
def find_ind(df_g):
列表_ind=[0]
arr=(np.subtract.outer(df_g.frame_int,df_g.frame_int)
arr = (np.subtract.outer(dfs.a, dfs.a) <=10).sum(0)
print (arr)
array([4, 4, 4, 5, 6, 7, 8, 8])
list_ind = [0] # initialize list of index to keep with 0
arr = (np.subtract.outer(dfs.a, dfs.a) <=10).sum(0)
i = arr[0]
while i < len(arr):
    list_ind.append(i)
    i = arr[i]

print (list_ind)
[0, 4, 6]

print (dfs.iloc[list_ind])
    a
0   1
4  14
6  30
# it seems you need to convert the column frame_no to integer
df['frame_int'] = pd.to_numeric(df['frame_no'])
df = df.sort_values('frame_int') #ensure data to be sorted by frame_int, whatever the global_id

#define the function looking for the ind
def find_ind (df_g):
    list_ind = [0]
    arr = (np.subtract.outer(df_g.frame_int, df_g.frame_int) <= 10).sum(0)
    i = arr[0]
    while i <len(arr):
        list_ind.append(i)
        i = arr[i]
    return df_g.iloc[list_ind]

#create the filtered dataframe
df_filtered = (df.groupby('global_id').apply(find_ind)
                 .drop('frame_int',axis=1).reset_index(drop=True))

print (df_filtered)
   seq_name     label  pedestrian_id  frame_no  global_id
0         1  crossing              1         1          1
1         1  crossing              2         1          2
2         1  crossing              2        12          2
3         1  crossing              2        29          2
4         2  crossing              1        34          3
5         2  crossing              1        49          3