在numpy / pandas中用group aggregate替换组的值

时间:2016-03-01 12:21:53

标签: python arrays numpy pandas

我在numpy数组X中有一个图像:

array([[ 0.01176471,  0.49019608,  0.01568627],
       [ 0.01176471,  0.49019608,  0.01568627],
       [ 0.00784314,  0.49411765,  0.00784314],
       ..., 
       [ 0.03921569,  0.08235294,  0.10588235],
       [ 0.09411765,  0.14901961,  0.18431373],
       [ 0.10196078,  0.15294118,  0.21568627]])

我在这个数组上运行了一个聚类器算法,以找到相似的颜色,并为每个像素Y提供另一个包含类的数组:

array([19, 19, 19, ..., 37, 20, 20], dtype=int32)

使用该群集的平均值替换群集中所有像素的颜色的最快,最漂亮和最蟒蛇的方法是什么?

我想出了以下代码:

import pandas as pd
import numpy as np
<...>
df = pd.DataFrame.from_records(X, columns=list('rgb'))
df['cls'] = Y
mean_colors = df.groupby('cls').mean().values
# as suggested in comments below
# for cls in range(len(mean_colors)):
#    X[Y==cls] = mean_colors[cls]
X = mean_colors[Y]

有没有办法只在熊猫中或只在numpy中这样做?

2 个答案:

答案 0 :(得分:1)

您可以将transform用于groupby对象,然后将.values结果分配给X

X = df.groupby('cls').transform(np.mean).values

有关tranfrom的{​​{1}}的信息:

help

答案 1 :(得分:1)

假设Y中存在所有标签,您可以使用basic-indexing -

mean_colors[Y]

对于多次索引到同一位置的情况,为了提高性能,您还可以使用np.take而不是纯索引,就像这样 -

np.take(mean_colors,Y,axis=0)

运行时测试 -

In [107]: X = np.random.rand(10000,3)

In [108]: Y = np.random.randint(0,100,(10000))

In [109]: np.allclose(np.take(mean_colors,Y,axis=0),mean_colors[Y])
Out[109]: True           # Verify approaches

In [110]: %timeit mean_colors[Y]
1000 loops, best of 3: 280 µs per loop

In [111]: %timeit np.take(mean_colors,Y,axis=0)
10000 loops, best of 3: 63.7 µs per loop