Group by with numpy.mean

2ledvvac  于 2023-08-05  发布在  其他
关注(0)|答案(4)|浏览(82)

如何计算以下每个workerid的平均值?下面是我的示例NumPy ndarray。第0列是workerid,第1列是纬度,第2列是经度。
我想计算每个workerid的平均纬度和经度。我想使用NumPy(ndarray)保留所有这些,而不转换为Pandas。

import numpy
from scipy.spatial.distance import cdist, euclidean
import itertools
from itertools import groupby

class WorkerPatientScores:

    '''
    I read from the Patient and Worker tables in SchedulingOptimization.
    '''
    def __init__(self, dist_weight=1):
        self.a = []

        self.a = ([[25302, 32.133598100000000, -94.395845200000000],
                   [25302, 32.145095132560200, -94.358041585705600],
                   [25302, 32.160400000000000, -94.330700000000000],
                   [25305, 32.133598100000000, -94.395845200000000],
                   [25305, 32.115095132560200, -94.358041585705600],
                   [25305, 32.110400000000000, -94.330700000000000],
                   [25326, 32.123598100000000, -94.395845200000000],
                   [25326, 32.125095132560200, -94.358041585705600],
                   [25326, 32.120400000000000, -94.330700000000000],
                   [25341, 32.173598100000000, -94.395845200000000],
                   [25341, 32.175095132560200, -94.358041585705600],
                   [25341, 32.170400000000000, -94.330700000000000],
                   [25376, 32.153598100000000, -94.395845200000000],
                   [25376, 32.155095132560200, -94.358041585705600],
                   [25376, 32.150400000000000, -94.330700000000000]])

        ndarray = numpy.array(self.a)
        ndlist = ndarray.tolist()
        geo_tuple = [(p[1], p[2]) for p in ndlist]
        nd1 = numpy.array(geo_tuple)
        mean_tuple = numpy.mean(nd1, 0)
        print(mean_tuple)

字符串
上面的输出是:
[ 32.14303108 -94.36152893]

ktecyv1j

ktecyv1j1#

您可以使用一些创造性的数组切片和where函数来解决这个问题。

means = {}
for i in numpy.unique(a[:,0]):
    tmp = a[numpy.where(a[:,0] == i)]
    means[i] = (numpy.mean(tmp[:,1]), numpy.mean(tmp[:,2]))

字符串
切片[:,0]是一种从2d数组中提取列(在本例中是第一列)的方便方法。为了得到平均值,我们从第一列中找到唯一的ID,然后对于每个ID,我们用where提取适当的行,并合并。最终结果是元组的dict,其中键是ID,值是包含其他两列的平均值的元组。当我运行它时,它会产生以下dict:

{25302.0: (32.1463644108534, -94.36152892856853),
 25305.0: (32.11969774418673, -94.36152892856853),
 25326.0: (32.12303107752007, -94.36152892856853),
 25341.0: (32.17303107752007, -94.36152892856853),
 25376.0: (32.15303107752007, -94.36152892856853)}

kpbpu008

kpbpu0082#

给定这个数组,我们希望按第一列分组,并取其他2列的平均值

X = np.asarray([[25302, 32.133598100000000, -94.395845200000000],
                [25302, 32.145095132560200, -94.358041585705600],
                [25302, 32.160400000000000, -94.330700000000000],
                [25305, 32.133598100000000, -94.395845200000000],
                [25305, 32.115095132560200, -94.358041585705600],
                [25305, 32.110400000000000, -94.330700000000000],
                [25326, 32.123598100000000, -94.395845200000000],
                [25326, 32.125095132560200, -94.358041585705600],
                [25326, 32.120400000000000, -94.330700000000000],
                [25341, 32.173598100000000, -94.395845200000000],
                [25341, 32.175095132560200, -94.358041585705600],
                [25341, 32.170400000000000, -94.330700000000000],
                [25376, 32.153598100000000, -94.395845200000000],
                [25376, 32.155095132560200, -94.358041585705600],
                [25376, 32.150400000000000, -94.330700000000000]])

字符串

只使用numpy,不使用循环

groups = X[:,0].copy()
X = np.delete(X, 0, axis=1)

_ndx = np.argsort(groups)
_id, _pos, g_count  = np.unique(groups[_ndx], 
                                return_index=True, 
                                return_counts=True)

g_sum = np.add.reduceat(X[_ndx], _pos, axis=0)
g_mean = g_sum / g_count[:,None]


在字典中存储结果:

>>> dict(zip(_id, g_mean))
{25302.0: array([ 32.14636441, -94.36152893]),
 25305.0: array([ 32.11969774, -94.36152893]),
 25326.0: array([ 32.12303108, -94.36152893]),
 25341.0: array([ 32.17303108, -94.36152893]),
 25376.0: array([ 32.15303108, -94.36152893])}

vawmfj5a

vawmfj5a3#

使用workerid和一个列表解析,它将是:

a=np.array(self.a)
ids=np.unique(a[:,0]) #array of unique ids
pos_mean=[np.mean(a[a[:,0]==i, 1:], axis=0) for i in ids]

字符串
但考虑到似乎总是有3个连续的测量,应该有一个相对容易的方法来矢量化它

tnkciper

tnkciper4#

添加我的两分钱-尽管@Marco的答案比公认的答案和我即将提出的建议性能更高-仍然,人们也可以使用NumPy的histogram函数来根据一些分组对给定的值求和。

labels, bin_labels, bin_counts = np.unique(X[:,0], return_inverse=True, return_counts=True)
bins = np.arange(len(labels)+1)
i = 1  # 1 for the second column, 2 for the next, etc.
s = np.histogram(bin_labels, weights=X[:,i], bins=bins)[0]
mean = s / bin_counts

字符串
现在mean代表labels中提到的每个标签的平均值。同样,这比np.add.reduceat慢,但我提供它作为替代方案,因为它可能可以用于其他目的...

相关问题