gpt4 book ai didi

python - Pandas:从受限列范围内的每一行获取随机子集的有效方法

转载 作者:太空宇宙 更新时间:2023-11-04 04:12:15 25 4
gpt4 key购买 nike

我有一些不同长度的数字时间序列存储在一个宽大的 pandas 数据框中。每行对应一个系列,每列对应一个测量时间点。由于它们的长度不同,这些系列可能在左侧(第一个时间点)或右侧(最后一个时间点)或两者都有缺失值 (NA) 尾部。每行总是有一个没有最小长度 NA 的连续条纹。

我需要从每一行中获取固定长度的随机子集,不包括任何 NA。理想情况下,我希望保持原始数据框完好无损,并在新数据框中报告子集。

我设法用一个非常低效的 for 循环获得了这个输出,它逐行遍历每一行,确定裁剪位置的开始,这样 NA 就不会包含在输出中并复制裁剪结果。这可行,但在大型数据集上速度极慢。这是代码:

import pandas as pd
import numpy as np
from copy import copy

def crop_random(df_in, output_length, ignore_na_tails=True):
# Initialize new dataframe
colnames = ['X_' + str(i) for i in range(output_length)]
df_crop = pd.DataFrame(index=df_in.index, columns=colnames)
# Go through all rows
for irow in range(df_in.shape[0]):
series = copy(df_in.iloc[irow, :])
series = np.array(series).astype('float')
length = len(series)
if ignore_na_tails:
pos_non_na = np.where(~np.isnan(series))
# Range where the subset might start
lo = pos_non_na[0][0]
hi = pos_non_na[0][-1]
left = np.random.randint(lo, hi - output_length + 2)
else:
left = np.random.randint(0, length - output_length)
series = series[left : left + output_length]
df_crop.iloc[irow, :] = series
return df_crop

还有一个玩具示例:

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 NaN NaN NaN 1 2 3 4 5 6
# 1 1 2 3 4 5 6 7 8 9
# 2 NaN NaN NaN 1 2 3 NaN NaN NaN

crop_random(df, 3)
# One possible output:
# X_0 X_1 X_2
# 0 2 3 4
# 1 7 8 9
# 2 1 2 3

我怎样才能以适应大型数据帧的方式获得相同的结果?

编辑:将我改进的解决方案移至答案部分。

最佳答案

我设法通过以下方式大大加快了速度:

def crop_random(dataset, output_length, ignore_na_tails=True):
# Get a random range to crop for each row
def get_range_crop(series, output_length, ignore_na_tails):
series = np.array(series).astype('float')
if ignore_na_tails:
pos_non_na = np.where(~np.isnan(series))
start = pos_non_na[0][0]
end = pos_non_na[0][-1]
left = np.random.randint(start,
end - output_length + 2) # +1 to include last in randint; +1 for slction span
else:
length = len(series)
left = np.random.randint(0, length - output_length)
right = left + output_length
return left, right

# Crop the rows to random range, reset_index to do concat without recreating new columns
range_subset = dataset.apply(get_range_crop, args=(output_length,ignore_na_tails, ), axis = 1)
new_rows = [dataset.iloc[irow, range_subset[irow][0]: range_subset[irow][1]]
for irow in range(dataset.shape[0])]
for row in new_rows:
row.reset_index(drop=True, inplace=True)

# Concatenate all rows
dataset_cropped = pd.concat(new_rows, axis=1).T

return dataset_cropped

关于python - Pandas:从受限列范围内的每一行获取随机子集的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56127995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com