创建包含来自一组 3 个一维向量的强度值的二维数组

Creating a 2D array containing values of intensities from a set of 3 1-D vectors

如果标题看起来含糊不清,我深表歉意,但我尽力了。无论如何,我有一个包含三列的数据框,一列包含日期时间值(用于观察时间),另一列包含范围(与进行观察的仪器的距离),最后一列包含观察的强度。此数据的散点图如下所示:

我需要过滤掉随机孤立的 'salt and pepper' 观察结果,并计划使用中值过滤器来执行此操作。但是,我不确定该怎么做。我试图创建一个包含根据时间和范围索引的强度值的二维数组。所以 00:00 UT 对应于第 0 行,0 km 对应于第 0 列,依此类推......空位置包含 NaN。然后,我将中值滤波器(scipy 的 medfilt:scipy.ndimage.median_filter)应用于此二维数组。

我的问题是它似乎效率低下,因为我必须遍历大量数据才能创建数组。当然,将过滤后的二维数组转换为相应的一维序列也很困难。

这是我用来获取二维数组的代码

def get2DData(df, filt_size):
    '''
    Implementing this method: We want a 2D array that stores all the LoS 
    velocities, so that we can ultimately apply median filtering to it. 
    
    To do this, iterate over all unique datetime values and all unique range values, 
    assigning LoS velocity values to the appropriate positions in a 2D array.
    '''
    
    arr = np.empty((len(df['time'].unique()), len(df['slist'].unique()), ))
    arr[:] = np.nan
    
    times_ = sorted(df['time'].unique())
    times_index = np.arange(len(times_))
    
    range_ = sorted(df['slist'].unique())
    range_index = np.arange(len(range_))
    
    times_dict = {A: B for A, B in zip(times_, times_index)}
    range_dict = {A: B for A, B in zip(range_, range_index)}
    
    times_dict_rev = {A: B for A, B in zip(times_index, times_)}
    range_dict_rev = {A: B for A, B in zip(range_index, range_)}
    
    for dt, rng_, v in zip(df['time'].values, df['slist'].values, df['v'].values):
        arr[times_dict[dt]][range_dict[rng_]] = v
    
    medfilt_arr = applyFilt(arr,filt_size)
    
    dt_list = []
    rng_list = []
    v_list = []
    for ix,iy in np.ndindex(medfilt_arr.shape):
        dt_list.append(times_dict_rev[ix])
        rng_list.append(range_dict_rev[iy])
        v_list.append(medfilt_arr[ix][iy])
    
    df_filtered = pd.DataFrame({'time': dt_list, 'slist': rng_list,'v': v_list})
    
    return arr, df_filtered

加速数组创建的一种方法可能是


def get2DArray(df):
    alltime = df['time'].to_numpy()
    allrange = df['slist'].to_numpy()

    unique_time = np.unique(alltime)
    unique_rang = np.unique(allrange)

    row = unique_time.searchsorted(alltime)
    col = unique_rang.searchsorted(allrange)

    arr = np.full((len(unique_time), len(unique_rang)), fill_value=np.NaN)
    arr[row, col] = df["v"].to_numpy()

    return arr

想法是使用所有可能值中时间和范围的相对位置来查找关联的 row/col,而不是使用字典。在我做的一些测试中,这个版本快了大约 5-7 倍,虽然不是很多,但已经很不错了