如何修改Python脚本实现不同长度连续相邻元素的随机抽取
问题说明
- 目标:处理148行、1500列的DataFrame,从每列中随机抽取长度为2、6、12、24的相邻连续点
- 约束:抽取连续点时禁止将序列首个观测值和末尾观测值相连
示例:数组
A=[2,9,7,6,0]抽取长度为2的连续点时
合法结果:(2,9)、(9,7)、(6,0)、(9,2)、(7,9)、(6,7)、(0,6)等
非法结果:(2,0)、(0,2)这类首尾跨接的组合,不得纳入抽样范围
- 现有可运行的随机非连续点抽取脚本如下:
df=data # My data set consists of 148 columns and 1500 rows for i in range(1): hr_ev = df.iloc[:,i] # select particular column N = 1000 # lengt of data C =4 # number of columns rand_hr = np.zeros(shape = (1000,4)) # empty array for u,j in zip([2, 6, 12, 24],range(C)): # intervals of random picking for i in range(N): x=np.random.choice(hr_ev, size=u, replace=True) # random picking c=np.sum(x) # sum of randomly picked observations rand_hr[i,j] = c df_hr = pd.DataFrame(rand_hr) print(df_hr)
实现方案
核心逻辑:连续片段抽取不需要随机挑选独立元素,只需要随机生成合法的起始索引,保证「起始索引+抽取长度」不超过序列总长度,即可完全避免首尾跨接的问题。
修改后的代码保留原脚本的输出逻辑,修复了连续抽取的问题:
import numpy as np import pandas as pd # 加载实际数据 df = data # 若需要遍历所有列,将range(1)改为range(df.shape[1])即可 for col_idx in range(1): hr_ev = df.iloc[:, col_idx].values N = 1000 # 单种长度的抽样次数 seq_len = len(hr_ev) rand_hr = np.zeros(shape=(N, 4)) for col_pos, sample_len in enumerate([2, 6, 12, 24]): # 计算合法起始索引的最大值:索引从0开始,最大起始位置为seq_len - sample_len max_valid_start = seq_len - sample_len # 批量生成N个合法起始索引 start_idx_list = np.random.randint(0, max_valid_start + 1, size=N) for row in range(N): s = start_idx_list[row] # 切片取连续sample_len个元素 continuous_sample = hr_ev[s : s + sample_len] rand_hr[row, col_pos] = continuous_sample.sum() df_hr = pd.DataFrame(rand_hr, columns=['sample_len2', 'sample_len6', 'sample_len12', 'sample_len24']) print(df_hr)
补充说明
- 上述代码默认对每个长度做1000次有放回连续抽样,即同一个连续片段可能被多次抽取
- 如果需要无放回抽样,将生成起始索引的代码替换为
start_idx_list = np.random.choice(np.arange(max_valid_start + 1), size=N, replace=False)即可,注意此时要求抽样次数N不能超过该长度对应的合法片段总数(即seq_len - sample_len + 1) - 输出列名可根据实际需求自行修改删除
内容的提问来源于stack exchange,提问作者Adnan
相关产品推荐
相关产品推荐

