2013-05-04 3 views
0
df = pd.DataFrame({'A':[11,11,22,22],'mask':[0,0,0,1],'values':np.arange(10,30,5)}) 
df 

    A mask values 
0 11 0 10 
1 11 0 15 
2 22 0 20 
3 22 1 25 

Теперь, как я могу группа по А, и сохранить имена столбцов в такт, и все же поместить пользовательскую функцию в Z:панды dataframe GroupBy как MySQL, но в новый столбец

def calculate_df_stats(dfs): 

    mask_ = list(dfs['B']) 
    mean = np.ma.array(list(dfs['values']), mask=mask_).mean() 
    return mean 

df['Z'] = df.groupby('A').agg(calculate_df_stats) # does not work 

и генерировать :

 A mask values Z 
0 11 0  10 12.5 
1 22 0  20 25 

Независимо от того, что я делаю, это заменяет столбец значений средним значением маскировки.

и может ли ваше решение применяться для функции на двух столбцах и вернуться в новый столбец?

Спасибо!

Edit: Для уточнения более: скажем, у меня есть такая таблица в Mysql:

SELECT * FROM `Reader_datapoint` WHERE `wavelength` = '560' 
LIMIT 200; 

, который дает мне такой результат: http://pastebin.com/qXiaWcJq

Если я бегу теперь это:

SELECT *, avg(action_value) FROM `Reader_datapoint` WHERE `wavelength` = '560' 
group by `reader_plate_ID`; 

Я получаю:

datapoint_ID plate_ID coordinate_x coordinate_y res_value wavelength ignore avg(action_value) 
193 1 0 0 2.1783 560 NULL 2.090027083333334 
481 2 0 0 1.7544 560 NULL 1.4695583333333333 
769 3 0 0 2.0161 560 NULL 1.6637885416666673 

Как я могу воспроизвести это поведение в Pandas? обратите внимание, что все имена столбцов остаются неизменными, первое значение берется и добавляется новый столбец.

+0

В вашем вопросе есть некоторые вещи, которые непонятны. 1) Что такое «B» в вашей функции? (Я полагаю, что это должна быть «маска»). 2) Какое значение вы хотите в столбце «values» в результирующем фреймворке? (в примере, который вы показываете, это первое значение) 3) Я также предполагаю, что значение 25 в столбце «Z» вашего результирующего массива должно быть 20? – joris

+0

Я обновил вопрос с лучшим примером. –

+0

Хорошо, но что возвращает MySQL для столбцов, где вы не подсчитываете что-то для (*)? Я думаю, что значение первой строки? Так что это то же самое, что и в моем ответе. И что такое 'action_value'? Вы имели в виду там '' res_value''? – joris

ответ

2

Если вы хотите оригинальные колонки в вашем результате, вы можете сначала вычислить сгруппированный и агрегированный dataframe (., Но вам придется агрегировать какой-то образом свои оригинальные колонки я взял первый произошедшей в качестве примера):

>>> df = pd.DataFrame({'A':[11,11,22,22],'mask':[0,0,0,1],'values':np.arange(10,30,5)}) 
>>> 
>>> grouped = df.groupby("A") 
>>> 
>>> result = grouped.agg('first') 
>>> result 
    mask values 
A    
11  0  10 
22  0  20 

, а затем добавить столбец «Z» для этого результата, применяя вашу функцию в результате GroupBy «сгруппированных»:

>>> def calculate_df_stats(dfs): 
...  mask_ = list(dfs['mask']) 
...  mean = np.ma.array(list(dfs['values']), mask=mask_).mean() 
...  return mean 
... 
>>> result['Z'] = grouped.apply(calculate_df_stats) 
>>> 
>>> result 
    mask values  Z 
A      
11  0  10 12.5 
22  0  20 20.0 

В определении функции вы всегда можете использовать несколько столбцов (только по имени) чтобы вернуть результат.

Смежные вопросы