对数据框应用掩码,但仅在数据框内的一定范围内



我目前有一些代码使用掩码来计算重载值的平均值,以及基线值。它在整个数据帧的长度上执行此操作。然而,现在我只想将其应用于数据框列中的某个范围,在firstlast值之间(即,列中的指定区域,由用户输入决定)。下面是我的代码:


mask_number = 5
no_overload_cycles = 1
hyst = pd.DataFrame({"test":[12, 4, 5, 4, 1, 3, 2, 5, 10, 9, 7, 5, 3, 6, 3, 2 ,1, 5, 2]})
list_test = []
for i in range(0,len(hyst)-1,mask_number):
for x in range(no_overload_cycles):
list_test.append(i+x)

mask = np.array(list_test)
print(mask)
[0 1 5 10 15 20]
first = 4
last = 17
regression_area = hyst.iloc[first:last]
mean_range_overload = regression_area.loc[np.where(mask == regression area.index)]['test'].mean()
mean_range_baseline = regression_area.drop(mask[first:last])['test'].mean()

因此,test中的过载平均值为5、10和15个周期,基线平均值为位置4至17,不包括5、10和15。这将是我期望的输出:

print (mean_range_overload)
4
print(mean_range_baseline)
4.545454

然而,no_overload_cycles值可以改变,例如,可以是3,这将创建一个掩码:


mask_number = 5
no_overload_cycles = 3
hyst = pd.DataFrame({"test":[12, 4, 5, 4, 1, 3, 2, 5, 10, 9, 7, 5, 3, 6, 3, 2 ,1, 5, 2]})
list_test = []
for i in range(0,len(hyst)-1,mask_number):
for x in range(no_overload_cycles):
list_test.append(i+x)
mask = np.array(list_test)
print(mask)
[0 1 2 5 6 7 10 11 12 15 16 17 20]

所以mean_range_overload将是5、6、7、10、11、12、15、16、17的平均值,mean_range_baseline将是这些值之间的值,在数据框列的firstlast的范围内。

任何帮助在这将是非常感激!

假设no_overload_cycles == 1始终存在,您可以简单地使用切片对象来索引DataFrame

假设您希望,在您的示例中,特别选择周期5、10和15,并将它们用作过载。然后你可以通过df.loc[5:15:5]得到它们。另一方面,如果您希望从您选择的范围中选择第5、第10和第15个周期,您可以通过执行df.iloc[5:15+1:5]来获得它们(iloc不包含正确的索引,因此我们添加一个)。不需要循环

正如评论中提到的,你的问题有点令人困惑,如果你能给出更好的描述和一些预期的结果,那将会很有帮助;一般来说,我还建议您在论坛上提出问题之前将问题的特定领域部分解耦,因为不是每个人都知道您所说的"超载"、"基线"、"周期"是什么意思。。我不评论,因为我还没有足够的声誉来这样做。

我重命名了一些变量,所以我称之为"掩码";不是你所谓的面具,但我认为这是你正试图使:

mask_length = 5
overload_cycles_per_mask = 3
df = pd.DataFrame({"test": [12, 4, 5, 4, 1, 3, 2, 5, 10, 9, 7, 5, 3, 6, 3, 2 ,1, 5, 2]})
selected_range = (4, 17)
overload_indices = []
baseline_indices = []
# `range` does not include the right hand side so we add one
# ideally you would specify the range as (4, 18) instead
for i in range(selected_range[0], selected_range[1]+1):
if i % mask_length < overload_cycles_per_mask:
overload_indices.append(i)
else:
baseline_indices.append(i)

print(overload_indices)
print(df.iloc[overload_indices].test.mean())
print(baseline_indices)
print(df.iloc[baseline_indices].test.mean())

基本上,selected_range中的DataFrame行被分成长度为mask_length的段,每段的第一个overload_cycles_per_mask元素被标记为过载,其他的作为基线。

这样,您将得到两个索引列表,您可以直接将其传递给df.iloc,因为根据文档,它支持整数列表。

以下是mask_length = 5overload_cycles_per_mask = 1的输出:

[5, 10, 15]
4.0
[4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17]
4.545454545454546

mask_length = 5overload_cycles_per_mask = 3:

[5, 6, 7, 10, 11, 12, 15, 16, 17]
3.6666666666666665
[4, 8, 9, 13, 14]
5.8

我相信将其称为单个掩码会使事情更加混乱。在任何情况下,我会把获得指标的逻辑放在某个单独的函数中,而不是计算平均值的函数。