【问题标题】:Replace values of a group with group aggregate in numpy/pandas用 numpy/pandas 中的组聚合替换组的值
【发布时间】:2016-03-01 12:21:52
【问题描述】:

我在一个 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)

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

我想出了以下代码:

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]

有没有办法只在 pandas 或只在 numpy 中做到这一点?

【问题讨论】:

  • 假设Y包含所有标签,那么简单的索引mean_colors[Y]怎么样?
  • 对于您的示例,您的代码不起作用,因为您在 Y 中有 3 个不同的值,您何时比较 Y==cls 没有任何反应,因为索引中没有...(cls只等于 0, 1, 2)
  • @Divakar 是的,很漂亮,谢谢!
  • @AntonProtopopov 它有效,我试过了。我在 Y 中没有 3 个值,我在 X 中有它们。
  • @Direvius 如果不复制您的结果,很难回答。您可以减少您的XY 并将它们附加到工作代码或生成mcve。无论如何,我有来自原始来源的数据,这只是对未来的建议

标签: python arrays numpy pandas


【解决方案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

【讨论】:

  • 在我的机器上,使用我的数据:纯索引是 6.13 ms,take 是 2.08 ms,df.groupby('cls').transform(np.mean).values 是 65.2 ms。我认为这两个是最好的=)
  • 啊,我没想到之前需要找到mean_colors
  • 纯索引:610 毫秒;取索引:604 ms;熊猫变换:659 毫秒
【解决方案2】:

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

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

来自help的关于tranfrom的信息:

transform(func, *args, **kwargs) method of pandas.core.groupby.DataFrameGroupBy instance
    Call function producing a like-indexed DataFrame on each group and
    return a DataFrame having the same indexes as the original object
    filled with the transformed values

    Parameters
    ----------
    f : function
        Function to apply to each subframe

    Notes
    -----
    Each subframe is endowed the attribute 'name' in case you need to know
    which group you are working on.

    Examples
    --------
    >>> grouped = df.groupby(lambda x: mapping[x])
    >>> grouped.transform(lambda x: (x - x.mean()) / x.std())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 2014-05-18
    • 2019-09-06
    • 2019-09-26
    • 2012-05-07
    • 2013-06-08
    • 1970-01-01
    相关资源
    最近更新 更多