【问题标题】:how to apply a sequence of conditions to np.where()如何将一系列条件应用于 np.where()
【发布时间】:2019-07-19 18:26:37
【问题描述】:

我需要计算 np.array 中相同元素的索引的平均值

我已经尝试使用 np.where 函数进行映射和列表理解,但它们返回我需要转换回 np.like 的 python 列表。 并且很遗憾自己无法从 numpy 中找到合适的东西,而且对 numpy 不太了解

有一个我尝试做的例子

A = np.array ([2,5,9,8,8,3,2,1,2,1,8])
set_ = np.unique(A)
indeces = [np.where(A==i) for i in set_]
mean_ = [np.mean(i) for i in indeces]

但是列表理解给出了一个列表,而 np.where - ndarray 我想使用 numpy 而不进行不必要的转换

我尝试使用 map 和 np.fromiter 之类的:

indeces = map(np.where,[A==i for i in set_])
mean_ = np.fromiter(indeces,dtype = np.int)

但它提供: ValueError: 使用序列设置数组元素。

mean_ = [8.0, 4.666666666666667, 5.0, 1.0, 5.666666666666667, 2.0]

使用上面的代码,但是请任何人都可以提出一种有效的方法来使用 numpy 或最接近的方法来完成此操作。 感谢关注)

【问题讨论】:

  • 您能否编辑您的问题以包含给定输入所需的输出?
  • 您能举例说明输出或最终结果应该是什么样子吗?

标签: python numpy


【解决方案1】:

如果A 中的值是非负整数,您可以通过两次调用np.bincount 来执行计算:

import numpy as np
A = np.array ([2,5,9,8,8,3,2,1,2,1,8])
result = np.bincount(A, weights=np.arange(len(A))) / np.bincount(A)
result = result[~np.isnan(result)]
print(result)

产量

[8.         4.66666667 5.         1.         5.66666667 2.        ]

如果A包含任意值,您可以先将值转换为非负整数标签,然后按上述进行:

import numpy as np
A = np.array ([2,5,9,8,8,3,2,1,2,1,8])+0.5
uniqs, B = np.unique(A, return_inverse=True)
result = np.bincount(B, weights=np.arange(len(B))) / np.bincount(B)
result = result[~np.isnan(result)]
print(result)

产量

[8.         4.66666667 5.         1.         5.66666667 2.        ]

工作原理:np.bincount 计算非负整数数组中每个值出现的次数:

In [161]: np.bincount(A)
Out[161]: array([0, 2, 3, 1, 0, 1, 0, 0, 3, 1])
                    |  |                 |  |
                    |  |                 |  o--- 9 occurs once
                    |  |                 o--- 8 occurs three times
                    |  o--- 2 occurs three times                       
                    o--- 1 occurs twice

如果提供了weight 参数,则不是将出现次数加1,而是将计数增加weight

In [162]: np.bincount(A, weights=np.arange(len(A)))
Out[163]: array([ 0., 16., 14.,  5.,  0.,  1.,  0.,  0., 17.,  2.])
                      |    |                             |     |
                      |    |                             |     o--- 9 occurs at index 2
                      |    |                             o--- 8 occurs at indices (3,4,10)
                      |    o--- 2 occurs at indices (0,6,8)
                      o--- 1 occurs at indices (7,9)

由于np.arange(len(A)) 等于A 中每个项目的索引值,因此上述对np.bincount 的调用将A 中每个值的索引相加。 将np.bincount 返回的两个数组相除得到平均索引值。


或者,使用Pandas,计算可以表示为groupby/mean operation

import numpy as np
import pandas as pd
A = np.array([2,5,9,8,8,3,2,1,2,1,8])
S = pd.Series(np.arange(len(A)))
print(S.groupby(A).mean().values)

产量

[8.         4.66666667 5.         1.         5.66666667 2.        ]

【讨论】:

  • 很好...但是如果 A 包含像 1e9 这样的大整数,它会使您的操作系统崩溃。此外,该解决方案对 A 中的非整数返回错误答案
猜你喜欢
  • 1970-01-01
  • 2019-05-22
  • 2020-06-19
  • 1970-01-01
  • 2016-08-04
  • 2021-09-01
  • 2014-02-12
  • 2019-06-21
  • 1970-01-01
相关资源
最近更新 更多