【问题标题】:Python DataFrame - groupby and centroid calculationPython DataFrame - 分组和质心计算
【发布时间】:2018-05-29 13:41:39
【问题描述】:

我有一个包含两列的数据框:一列包含类别,另一列包含 300 维向量。对于 Category 列中的每个值,我有很多 300 维向量。我需要的是按类别列对数据框进行分组,同时获取属于每个类别的所有向量的质心值。

Category        Vector   
Balance        [1,2,1,-5,....,9]  
Inquiry        [-5,3,1,5,...,10]  
Card           [-3,1,2,3,...1]  
Balance        [1,3,-2,1,-5,...,7]  
Card           [3,1,3,4,...,2]  

所以在上述情况下,所需的输出将是:

Category       Vector   
Balance        [1,2.5,-0.5,-2,....,8]  
Inquiry        [-5,3,1,5,...,10]  
Card           [0,1,2.5,3.5,...,1.5]  

我已经编写了以下函数,它获取向量数组并计算其质心:

import numpy as np
    def get_intent_centroid(array):
        centroid = np.zeros(len(array[0]))
        for vector in array:
            centroid = centroid + vector
        return centroid/len(array)    

所以我只需要一种快速的方法来应用上面的函数以及数据帧上的groupby 命令。

请原谅我对数据框的格式设置,但我不知道如何正确格式化它们。

【问题讨论】:

  • 不确定如何在 pandas 中对列中的向量进行操作,但您可以尝试将这两列更改为列表,然后进行操作并转换回 pandas!
  • 我认为如果不使用列表,整个计算过程会快得多。
  • @Tarun 你会如何使用列表来处理它?
  • 我已经发布了答案。如果你在 pandas 中找不到方法,你可以这样做

标签: python arrays dataframe centroid


【解决方案1】:

所以向量列表的质心就是向量每个维度的平均值,所以可以大大简化为这个。

df.groupby('Category')['Vector'].apply(lambda x: np.mean(x.tolist(), axis=0))

它应该比任何循环/列表转换方法都快。

【讨论】:

    【解决方案2】:

    按照 OP 的要求,我有办法通过列表来完成:

    vectorsList = list(df["Vector"])
    catList = list(df["Category"])
    
    #create a dict for each category and initialise it with a list of 300, zeros
    dictOfCats = {}
    for each in set(cat):
        dictOfCats[each]= [0] * 300
    
    #loop through the vectorsList and catList
    for i in range(0, len(catList)):
        currentVec = dictOfCats[each]
        for j in range(0, len(vectorsList[i])):
            currentVec[j] = vectorsList[i][j] + currentVec[j]
        dictOfCats[each] = currentVec
    
    #now each element in dict has sum. you can divide it by the count of each category
    #you can calculate the frequency by groupby, here since i have used only lists, i am showing execution by lists
    catFreq = {} 
    for eachCat in catList:
        if(eachCat in catList):
            catList[eachCat] = catList[eachCat] + 1
        else:
            catList[eachCat] = 1
    
    
    for eachKey in dictOfCats:
        currentVec = dictOfCats[eachKey]
        newCurrentVec = [x / catList[eachKey] for x in currentVec]
        dictOfCats[eachKey] = newCurrentVec
    
    #now change this dictOfCats to dataframe again
    

    请注意,代码中可能存在错误,因为我没有使用您的数据进行检查。这在计算上会很昂贵,但如果您无法通过 pandas 找到解决方案,则应该可以完成这项工作。如果您确实在 pandas 中提出了解决方案,请发布答案

    【讨论】:

      【解决方案3】:
      import pandas as pd
      import numpy as np
      
      df = pd.DataFrame(
          [
              {'category': 'Balance', 'vector':  [1,2,1,-5,9]},
              {'category': 'Inquiry', 'vector': [-5,3,1,5,10]},
              {'category': 'Card', 'vector': [-3,1,2,3,1]},
              {'category': 'Balance', 'vector':  [1,3,-2,1,7]},
              {'category': 'Card', 'vector':  [3,1,3,4,2]}
          ]
      )
      
      
      def get_intent_centroid(array):
          centroid = np.zeros(len(array[0]))
          for vector in array:
              centroid = centroid + vector
          return centroid/len(array)
      
      
      df.groupby('category')['vector'].apply(lambda x: get_intent_centroid(x.tolist()))
      
      Output:
      
      category
      Balance    [1.0, 2.5, -0.5, -2.0, 8.0]
      Card         [0.0, 1.0, 2.5, 3.5, 1.5]
      Inquiry    [-5.0, 3.0, 1.0, 5.0, 10.0]
      Name: vector, dtype: object
      

      【讨论】:

        【解决方案4】:

        这应该可以在不使用列表的情况下工作

        def get_intent_centroid(array):
            centroid = np.zeros(len(array.iloc[0]))
            for vector in array:
                centroid = centroid + vector
            return centroid/len(array.iloc[0])
        
        df.groupby('Catagory')['Vector'].apply(get_intent_centroid)
        

        【讨论】:

          猜你喜欢
          • 2015-06-04
          • 1970-01-01
          • 2017-11-02
          • 1970-01-01
          • 2017-06-18
          • 2012-04-06
          • 2019-05-12
          • 2022-11-21
          相关资源
          最近更新 更多