当前位置: 首页 > 知识库问答 >
问题:

如何通过dataframe列中的正数和负数范围构建窗口?

司信厚
2023-03-14

我想得到每个正负范围的平均值和最大值。根据以下样本数据:

import pandas as pd
test_list = [-1, -2, -3, -2, -1, 1, 2, 3, 2, 1, -1, -4, -5, 2 ,4 ,7  ]
df_test = pd.DataFrame(test_list, columns=['value'])

这给了我这样的数据帧:

    value
0      -1
1      -2
2      -3
3      -2
4      -1
5       1
6       2
7       3
8       2
9       1
10     -1
11     -4
12     -5
13      2
14      4
15      7

我想要这样的东西:

AVG1 = [-1, -2, -3, -2, -1] / 5 = - 1.8
Max1 = -3
AVG2 = [1, 2, 3, 2, 1] / 5 = 1.8 
Max2 = 3
AVG3 = [2 ,4 ,7] / 3 =  4.3
Max3 = 7

若解决方案需要新的列或新的数据帧,那个对我来说是可以的。

我知道我可以用。这里的平均值是四舍五入值的列平均值/平均值,但这个解给出了所有正值和所有负值的平均值。

如何建立一个窗口,我可以从第一个负组计算平均值,然后从第二个正组计算平均值,等等。。

当做

共有1个答案

常俊爽
2023-03-14

您可以通过np创建系列。符号用于区分阳性组和阴性组,将移位值与组的累计和进行比较,然后将平均值最大值

s = np.sign(df_test['value'])
g = s.ne(s.shift()).cumsum()
df = df_test.groupby(g)['value'].agg(['mean','max'])
print (df)
           mean  max
value               
1     -1.800000   -1
2      1.800000    3
3     -3.333333   -1
4      4.333333    7

编辑:

对于查找区域设置极端值,使用以下答案的解决方案:

test_list = [-1, -2, -3, -2, -1, 1, 2, 3, 2, 1, -1, -4, -5, 2 ,4 ,7  ]
df_test = pd.DataFrame(test_list, columns=['value'])

from scipy.signal import argrelextrema

#https://stackoverflow.com/a/50836425
n=2 # number of points to be checked before and after 
# Find local peaks
df_test['min'] = df_test.iloc[argrelextrema(df_test.value.values, np.less_equal, order=n)[0]]['value']
df_test['max'] = df_test.iloc[argrelextrema(df_test.value.values, np.greater_equal, order=n)[0]]['value']

然后,在极端值之后替换为缺失值,分别用于阴性组和阳性组:

s = np.sign(df_test['value'])
g = s.ne(s.shift()).cumsum()

df_test[['min1','max1']] = df_test[['min','max']].notna().astype(int).iloc[::-1].groupby(g[::-1]).cumsum()
df_test['min1'] = df_test['min1'].where(s.eq(-1) & df_test['min1'].ne(0))
df_test['max1'] = df_test['max1'].where(s.eq(1) & df_test['max1'].ne(0))

df_test['g'] = g
print (df_test)
    value  min  max  min1  max1  g
0      -1  NaN -1.0   1.0   NaN  1
1      -2  NaN  NaN   1.0   NaN  1
2      -3 -3.0  NaN   1.0   NaN  1
3      -2  NaN  NaN   NaN   NaN  1
4      -1  NaN  NaN   NaN   NaN  1
5       1  NaN  NaN   NaN   1.0  2
6       2  NaN  NaN   NaN   1.0  2
7       3  NaN  3.0   NaN   1.0  2
8       2  NaN  NaN   NaN   NaN  2
9       1  NaN  NaN   NaN   NaN  2
10     -1  NaN  NaN   1.0   NaN  3
11     -4  NaN  NaN   1.0   NaN  3
12     -5 -5.0  NaN   1.0   NaN  3
13      2  NaN  NaN   NaN   1.0  4
14      4  NaN  NaN   NaN   1.0  4
15      7  NaN  7.0   NaN   1.0  4

因此,可以分别聚合每组的最后3个值与lambda函数和均值,在min1max1中缺少值的行在Groupby中默认被删除:

df1 = df_test.groupby(['g','min1'])['value'].agg(lambda x: x.tail(3).mean())
print (df1)
g  min1
1  1.0    -2.000000
3  1.0    -3.333333
Name: value, dtype: float64

df2 = df_test.groupby(['g','max1'])['value'].agg(lambda x: x.tail(3).mean())
print (df2)
g  max1
2  1.0     2.000000
4  1.0     4.333333
Name: value, dtype: float64
 类似资料:
  • 问题内容: 考虑以下代码: 它将返回30到20之间的随机数。但是,我需要它的范围包括负数。 我如何在这一代中包括负数? 我曾尝试使用会是负数的数学,但这导致了错误。简单地减去或加上负数将不会产生所需的值。 编辑: 对不起,我只有半醒。正确的代码是。 问题答案: 要使用和获取设置范围内的随机数: 也适用于负数 所以: 会产生介于-10和30之间的随机整数。 也可以加倍

  • 如果我做:Math.random() * 4-2 这会让我得到一个范围(-2,2),2是排他性的吗?我认为这是正确的,但我很少得到正数(是的,我知道这是一个随机算法,我们必须无限随机地生成它才能感觉到,但我只是想确保) 新问题 如果我想要所有从-1到1的随机有理数,两个边界都包括在内,那么这条线是否有效:Math.random() * 2.00000000000000001 - 1; 我查了一下,

  • 间隔由开始和结束定义。 给定一组可能重叠的区间(例如,0-999),构建一个数据结构,以最佳时间复杂度支持以下范围查询 . 重叠(开始,结束)=与[开始,结束]重叠的所有间隔的集合 内(开始,结束)=位于[开始,结束]内的所有间隔的集合 哪里

  • 我必须制作一个程序,允许用户输入整数,直到按下“0”。程序必须打印:1)输入数字的总数2)正数3)正数的平均数4)负数5)负数的总和 到目前为止,我所能做的就是“输入直到按下‘0’”,并找到输入的数字的数量,这对我和我的编程技能来说是非常重要的。我很难找出这个数字是正数还是负数。也许我没有正确地比较他们,所以如果我能得到一些高级人员的帮助,我会很高兴。 这是我到目前为止的代码:

  • 问题内容: 如何从其父范围调用在子范围中定义的方法? http://jsfiddle.net/wUPdW/ 问题答案: 您可以从父母到孩子使用: 工作jsfiddle:http : //jsfiddle.net/wUPdW/2/ 更新 :还有另一个版本,耦合性更低,更易于测试: jsfiddle:http : //jsfiddle.net/uypo360u/