2014-01-22 3 views
3

У меня есть набор данных с весами для каждого наблюдения, и я хочу подготовить взвешенные резюме, используя groupby, но я ржавый относительно того, как лучше всего это сделать. Я думаю, что это подразумевает пользовательскую функцию агрегации. Моя проблема заключается в том, как правильно обрабатывать не элементарные данные, а групповые данные. Возможно, это означает, что лучше всего делать это шаг за шагом, а не за один раз.pandas: groupby и переменные веса

В псевдокоде Ищу

#first, calculate weighted value 
for each row: 
    weighted jobs = weight * jobs 
#then, for each city, sum these weights and divide by the count (sum of weights) 
for each city: 
    sum(weighted jobs)/sum(weight) 

Я не знаю, как работать «для каждого города» -часть в пользовательские функции совокупного и получить доступ к резюме на уровне группы.

Ложные данные:

import pandas as pd 
import numpy as np 
np.random.seed(43) 

## prep mock data 
N = 100 
industry = ['utilities','sales','real estate','finance'] 
city = ['sf','san mateo','oakland'] 
weight = np.random.randint(low=5,high=40,size=N) 
jobs = np.random.randint(low=1,high=20,size=N) 
ind = np.random.choice(industry, N) 
cty = np.random.choice(city, N) 
df_city =pd.DataFrame({'industry':ind,'city':cty,'weight':weight,'jobs':jobs}) 

ответ

6

Просто умножать две колонки:

In [11]: df_city['weighted_jobs'] = df_city['weight'] * df_city['jobs'] 

Теперь вы можете GroupBy город (и взять сумму):

In [12]: df_city_sums = df_city.groupby('city').sum() 

In [13]: df_city_sums 
Out[13]: 
      jobs weight weighted_jobs 
city         
oakland  362  690   7958 
san mateo 367 1017   9026 
sf   253  638   6209 

[3 rows x 3 columns] 

Теперь вы можете разделите две суммы, чтобы получить желаемый результат:

In [14]: df_city_sums['weighted_jobs']/df_city_sums['jobs'] 
Out[14]: 
city 
oakland  21.983425 
san mateo 24.594005 
sf   24.541502 
dtype: float64 
+0

определенно работоспособный - отлично! Я буду делать взвешивание для многих переменных и хотел бы включить в группу функцию, которую я мог бы назвать на лету; изменять уровни группировки и т. д. Любой способ это можно сделать за один шаг (т. е. в групповом вызове, передавая пользовательскую функцию с уровнем группировки, переменную для взвешивания как аргументы?) – ako

+1

. вы можете использовать groupby apply с помощью 'def f (x): return (1. * x ['weight'] * x ['jobs']). sum()/x ['jobs']. sum()', но это вероятно, будет менее эффективным, чем выше. –