Python Pandas:从受限列范围内的每行中获取随机子集的有效方法
我有一些不同长度的数字时间序列存储在一个大数据帧中。每行对应一个序列,每列对应一个测量时间点。由于长度不同,这些序列可能会有左(第一个时间点)或右(最后一个时间点)或两者的缺失值(NA)尾部。每行上始终有一条没有最小长度NA的连续条纹 我需要从每一行中获得固定长度的随机子集,不包括任何NA。理想情况下,我希望保持原始数据帧不变,并在新数据帧中报告子集 我通过一个非常低效的for循环获得了这个输出,该循环一行一行地遍历每一行,确定裁剪位置的开始,这样NAs就不会包含在输出中,并复制裁剪结果。这是可行的,但在大型数据集上速度非常慢。代码如下:Python Pandas:从受限列范围内的每行中获取随机子集的有效方法,python,pandas,subset,Python,Pandas,Subset,我有一些不同长度的数字时间序列存储在一个大数据帧中。每行对应一个序列,每列对应一个测量时间点。由于长度不同,这些序列可能会有左(第一个时间点)或右(最后一个时间点)或两者的缺失值(NA)尾部。每行上始终有一条没有最小长度NA的连续条纹 我需要从每一行中获得固定长度的随机子集,不包括任何NA。理想情况下,我希望保持原始数据帧不变,并在新数据帧中报告子集 我通过一个非常低效的for循环获得了这个输出,该循环一行一行地遍历每一行,确定裁剪位置的开始,这样NAs就不会包含在输出中,并复制裁剪结果。这是可
将熊猫作为pd导入
将numpy作为np导入
从副本导入副本
def crop_random(df_in,输出长度,忽略尾部=真):
#初始化新数据帧
colnames=['X_'+str(i)表示范围内的i(输出长度)]
df_crop=pd.DataFrame(index=df_in.index,columns=colnames)
#穿过所有的行
对于范围内的irow(df_in.shape[0]):
series=复制(df_in.iloc[irow,:])
series=np.array(series.astype('float'))
长度=长度(系列)
如果忽略尾部:
pos_non_na=np.where(~np.isnan(系列))
#子集可能开始的范围
lo=pos_non_na[0][0]
hi=位置不适用[0][1]
左=np.random.randint(低、高-输出长度+2)
其他:
左=np.random.randint(0,长度-输出长度)
系列=系列[左:左+输出长度]
df_crop.iloc[irow,:]=系列
返回df_作物
还有一个玩具的例子:
df=pd.DataFrame.from_dict({'t0':[np.NaN,1,np.NaN],
‘t1’:[np.NaN,2,np.NaN],
‘t2’:[np.NaN,3,np.NaN],
‘t3’:[1,4,1],
‘t4’:[2,5,2],
‘t5’:[3,6,3],
‘t6’:[4,7,np.NaN],
"t7":[5,8,np.NaN],,
‘t8’:[6,9,np.NaN]})
#t0 t1 t2 t3 t4 t5 t6 t7 t8
#0楠楠楠1 2 3 4 5 6
# 1 1 2 3 4 5 6 7 8 9
#2楠楠1 2 3楠楠楠
随机作物(df,3)
#一种可能的输出:
#X_0 X_1 X_2
# 0 2 3 4
# 1 7 8 9
# 2 1 2 3
我如何能够以适应大型数据帧的方式获得相同的结果
编辑:将改进后的解决方案移至“答案”部分。我成功地通过以下方法大大加快了速度:
def crop\u random(数据集、输出长度、忽略长度=True):
#获取每行要裁剪的随机范围
def get_range_裁剪(系列、输出长度、忽略尾部):
series=np.array(series.astype('float'))
如果忽略尾部:
pos_non_na=np.where(~np.isnan(系列))
start=pos_non_na[0][0]
结束=位置不适用[0][1]
左=np.random.randint(开始,
结束-输出_长度+2)#+1,包括randint中的last+截面跨度为1
其他:
长度=长度(系列)
左=np.random.randint(0,长度-输出长度)
右=左+输出长度
向左、向右返回
#将行裁剪为随机范围,重置索引以执行concat,而不重新创建新列
范围子集=数据集。应用(获取范围裁剪,参数=(输出长度,忽略尾部),轴=1)
新的_行=[dataset.iloc[irow,range_子集[irow][0]:range_子集[irow][1]]
对于范围内的irow(dataset.shape[0])]
对于新行中的行:
行重置索引(drop=True,inplace=True)
#连接所有行
数据集\u裁剪=pd.concat(新的\u行,轴=1).T
返回数据集\u已裁剪