2017-12-15 4 views
3

두 개의 열이있는 데이터 프레임이 있습니다. 하나는 범주를 포함하고 다른 하나는 300 차원 벡터를 포함합니다. 카테고리 열의 각 값에 대해 저는 300 차원 벡터가 많이 있습니다. 필요한 것은 Category 열에 의해 데이터 프레임을 그룹화하는 동시에 각 Category와 관련된 모든 벡터의 중심 값을 얻는 것입니다. 파이썬 DataFrame - groupby 및 centroid 계산

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] 

그래서 상기 경우에 원하는 출력 될 것이다 :

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)  

:

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] 

이미 그 중심을 벡터의 어레이를 얻고 산출 다음 함수를 작성한 그래서 위의 함수를 데이터 프레임에 groupby 명령과 함께 적용하는 빠른 방법이 필요합니다.

내 서식 데이터 프레임을 용서해주십시오. 그러나 올바르게 서식을 지정하는 방법을 모르겠습니다. 영업의 요청에 따라

+0

팬더의 열에서 벡터를 조작하는 방법을 잘 모르겠지만이 두 열을 목록으로 변경 한 다음 조작을 수행하고 팬더로 다시 변환 해보십시오! – Tarun

+0

목록을 사용하지 않으면 전체 계산 절차가 훨씬 빨라질 것이라고 생각합니다. –

+0

@ Tarun 목록을 사용하여 어떻게 접근합니까? –

답변

2

그래서 벡터의 목록의 중심이 각각의 단지 평균 인 사용을 나열하지 않고 대답

1

, 나는 목록을 통해 그것을 할 수있는 방법이 있습니다

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 

나는 당신의 데이터를 확인하지 않았기 때문에 코드의 버그가있을 수 있습니다. 이것은 계산적으로 비싸지 만 판다로 솔루션을 파악할 수없는 경우 작업을 수행해야합니다. 당신은 팬더의 솔루션을 가지고 올 경우,

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) 
0
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 
0

이 작동합니다을 게시하시기 바랍니다 벡터의 차원이므로이 작업을 단순화 할 수 있습니다.

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

그것은 어떤 루프 /리스트 변환 방법보다 빠를 것이다.