2017-12-15 63 views
3

私は2つの列を持つデータフレームを持っています.1つはカテゴリを含み、もう1つは300次元ベクトルを含んでいます。 Category列の各値には、300次元のベクトルがたくさんあります。私が必要とするのは、カテゴリの列でデータフレームをグループ化すると同時に、各カテゴリに関係するすべてのベクトルの重心値を取得することです。Python DataFrame - グループバイと重心計算

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] 

Iはすでにベクトルの配列を取得し、その重心を計算する次の関数を記述した:

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コマンドと一緒に適用するための素早い方法が必要です。

私のデータフレームの書式は間違いありませんが、正しくフォーマットする方法はわかりません。

+0

パンダの列のベクトルを操作する方法がわかりませんが、これらの2つの列をリストに変更してから操作して、パンダに戻すことができます! – Tarun

+0

私は、リストを使わないと計算の手続きがずっと速くなると思います。 –

+0

@ Tarunリストを使ってどのようにアプローチしますか? –

答えて

2

を使用せずに動作するはずですので、ベクトルのリストの重心は、それぞれのちょうど平均でありますベクトルの次元であるため、これを大幅に単純化することができます。

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

これは、任意のループ/リスト変換方法よりも高速である必要があります。

1

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 

私はあなたのデータでそれをチェックしていないので、コードにバグがあるかもしれないことに注意してください。これは計算上高価ですが、パンダによる解決策を見つけられない場合は、その作業を行う必要があります。あなたはパンダで解決策を考え出す行う場合は、答えを投稿してください

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

これはリスト

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) 
関連する問題