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

需要Numpy帮助:如何使用布尔值计算范围并在范围内将值相加?

宗政功
2023-03-14

我有一个Nx2矩阵,例如:

M = [[10, 1000],
 [11, 200],
 [15, 800],
 [20, 5000],
 [28, 100],
 [32, 3000],
 [35, 3500],
 [38, 100],
 [50, 5000],
 [51, 100],
 [55, 2000],
 [58, 3000],
 [66, 4000],
 [90, 5000]]

我需要创建一个Nx3矩阵,它以以下方式反映第一个矩阵中的行之间的关系:

使用右列标识范围边界的候选对象,条件为value

此条件适用于矩阵:

[[10, 1000],
 [20, 5000],
 [32, 3000],
 [35, 3500],
 [50, 5000],
 [55, 2000],
 [58, 3000],
 [66, 4000],
 [90, 5000],]

到目前为止,我提出了“M[M[:,1]

到目前为止我想到的是:np。差异(M[:,0])

[True, False, True, False, True, True, True, False]

这就是我被困的地方。我想用这个条件来定义一个范围的上下边界。例如:

[[10, 1000], #<- Range 1 start
 [20, 5000], #<- Range 1 end (as 32 would be 12 points away)
 [32, 3000], #<- Range 2 start
 [35, 3500], #<- Range 2 end
 [50, 5000], #<- Range 3 start
 [55, 2000], #<- Range 3 cont (as 55 is only 5 points away)
 [58, 3000], #<- Range 3 cont
 [66, 4000], #<- Range 3 end
 [90, 5000]] #<- Range 4 start and end (as there is no point +-10)

最后,回到第一个矩阵,我想为边界内(包括边界)的每个范围添加右列值。

所以我有四个范围来定义边界的开始和停止。

  • 范围1:开始10,结束20
  • 范围2:开始32,结束35
  • 范围3:开始50,结束66
  • 范围4:开始90,结束90

生成的矩阵如下所示,其中第0列是开始边界,第1列是结束边界,第2列是矩阵M在开始和结束之间的右列的加值。

[[10, 20, 7000], # 7000 = 1000+200+800+5000
 [32, 35, 6500], # 6500 = 3000+3500
 [50, 66, 14100], # 14100 = 5000+100+2000+3000+4000
 [90, 90, 5000]] # 5000 = just 5000 as upper=lower boundary

我在第二步卡住了,在我得到范围边界的真/假值之后。但是如何从布尔值创建范围,然后如何在这些范围内一起添加值,我还不清楚。感谢任何建议。此外,我不确定我的方法,也许有更好的方法从第一个矩阵到最后一个矩阵,也许跳过一步??

因此,我对中间步骤做了进一步的处理,现在可以返回范围的起始值和结束值:

start_diffs = np.diff(M[:,0]) > 10
start_indexes = np.insert(start_diffs, 0, True)

end_diffs = np.diff(M[:,0]) > 10
end_indexes = np.insert(end_diffs, -1, True)

start_values = M[:,0][start_indexes]
end_values = M[:,0][end_indexes]

print(np.array([start_values, end_values]).T)

回报:

[[10 20]
 [32 35]
 [50 66]
 [90 90]]

现在缺少的是如何使用这些范围来计算右列矩阵M的和。

共有1个答案

刘永望
2023-03-14

如果您愿意使用熊猫,这里有一个解决方案,回想起来似乎有点想多了,但有效:

# Initial array
M = np.array([[10, 1000],
              [11, 200],
              [15, 800],
              [20, 5000],
              [28, 100],
              [32, 3000],
              [35, 3500],
              [38, 100],
              [50, 5000],
              [51, 100],
              [55, 2000],
              [58, 3000],
              [66, 4000],
              [90, 5000]])

# Build a DataFrame with default integer index and column labels
df = pd.DataFrame(M)

# Get a subset of rows that represent potential interval edges
subset = df[df[1] >= 1000].copy()

# If a row is the first row in a new range, flag it with 1.
# Then cumulatively sum these 1s. This labels each row with a 
# unique integer, one per range
subset[2] = (subset[0].diff() > 10).astype(int).cumsum()

# Get the start and end values of each range
edges = subset.groupby(2).agg({0: ['first', 'last']})
edges
          0     
  first last
2           
0    10   20
1    32   35
2    50   66
3    90   90

# Build a pandas IntervalIndex out of these interval edges
tups = list(edges.itertuples(index=False, name=None))
idx = pd.IntervalIndex.from_tuples(tups, closed='both')

# Build a Series that maps each interval to a unique range number
mapping = pd.Series(range(len(idx)), index=idx)

# Apply this mapping to create a new column of the original df
df[2] = [mapping.loc[i] if idx.contains(i) else None for i in df[0]]
df
     0     1    2
0   10  1000  0.0
1   11   200  0.0
2   15   800  0.0
3   20  5000  0.0
4   28   100  NaN
5   32  3000  1.0
6   35  3500  1.0
7   38   100  NaN
8   50  5000  2.0
9   51   100  2.0
10  55  2000  2.0
11  58  3000  2.0
12  66  4000  2.0
13  90  5000  3.0

# Group by this new column, get edges of each interval, 
# sum values, and get the underlying numpy array
df.groupby(2).agg({0: ['first', 'last'], 1: 'sum'}).values
array([[   10,    20,  7000],
       [   32,    35,  6500],
       [   50,    66, 14100],
       [   90,    90,  5000]])
 类似资料:
  • 问题内容: 我有一个NumPy值数组。我想计算在特定范围内有多少这些值,例如x <100和x> 25。我已经读过有关计数器的信息,但它似乎仅对指定值有效,对值范围无效。我已经搜索过,但是没有发现有关我的特定问题的任何信息。如果有人可以指出适当的文档,我将不胜感激。谢谢 我已经试过了 但这只是给我25到99之间的数字。 编辑 我正在使用的数据是由另一个程序创建的。然后,我使用脚本读取数据并将其存储为

  • 我参加了一个编程比赛,我无法解决问题,问题是: 给定一个n个整数的数组A,我需要计算给定范围内求逆的次数。提供一个整数m,它表示范围的数量,然后是m行,在每一行中给出两个整数li和ri。 我们必须只计算指定范围内的反转,即从li到ri(包括0)的反转(基于0的索引)。 如果 A[i] 两个元素 A[i] 和 A[j] 添加到反演中 反转是: 输入: 输出: 约束: 我知道在整个数组上计算O(nlo

  • 我想获得一个每月平均值,该平均值仅计算包含交易的月份。这就像将所有交易金额相加,然后除以使用的月数一样简单。 我找不到一个本机Excel公式可以像这样计算月份,并且尝试使用表或命名范围对基于ROW()函数的条件求和不起作用。它只会在尝试按年(或任何其他条件)限制计数时返回零。 该公式如下所示: 顺便说一句,这是一个数组公式。它基本上会查看您所在的行是否与排序列表中引用月份的第一行相同。这是我尝试过

  • 我的Windows8应用程序有一个持续存在的问题。

  • 问题内容: 我正在制作一个要使用范围滑块的网站(我知道它仅支持Webkit浏览器)。 我已经将其完全集成并且可以正常工作。但我想使用a 来显示当前的幻灯片值。 我的意思是,如果最初滑块的值为5,那么在文本框中它应显示为5,当我滑动文本框时,其值应更改。 我可以仅使用还是使用。我想避免。可能吗? 问题答案: 这使用javascript,而不直接使用jquery。它可能有助于您入门。

  • 问题内容: 我看到该范围返回键和值的“副本”。有没有办法让该范围返回该商品的地址?例 http://play.golang.org/p/AFOGG9NGpx 这里“ field”没有被修改,因为range发送了field的副本,我是否必须使用index或是否有其他方法可以修改值? 谢谢阅读。 问题答案: 简短而直接的答案: 不,使用数组索引而不是值 因此,上面的代码变为: