2015-04-21 4 views
2

Я пытаюсь создать новый столбец «счет/id.size» для моего текущего dataframeНовая колонка на основе размера одного столбца

np.random.seed(1234) 
test = pd.DataFrame({'id':np.random.randint(1,5,10), 
        'score':np.random.uniform(0,1,10)}) 

test = test.sort(['id']) 

test 
    id  score 
4 1 0.875933 
5 1 0.357817 
6 1 0.500995 
3 2 0.958139 
7 2 0.683463 
9 2 0.370251 
2 3 0.801872 
0 4 0.272593 
1 4 0.276464 
8 4 0.712702 

Я хочу, чтобы мой новый dataframe быть таким:

id  score  score/id.size 
4 1 0.875933  0.875933/3 
5 1 0.357817  0.357817/3 
6 1 0.500995  0.500995/3 
3 2 0.958139  0.958139/3 
7 2 0.683463  0.683463/3 
9 2 0.370251  0.370251/3 
2 3 0.801872  0.801872/1 
0 4 0.272593  0.272593/3 
1 4 0.276464  0.276464/3 
8 4 0.712702  0.712702/3 

Извините, если этот вопрос слишком прост, я новичок в Python.

Спасибо!

+1

сделать вы хотите, чтобы первое значение в новом столбце буквально быть «0,875933/3», или вы хотите, чтобы это было 0,29197766. , , результат деления 0,87. , , на 3? – dbliss

+0

Извините за путаницу, я хочу, чтобы это было 0.29197766. Я сделал это таким образом для целей визуализации/ –

+0

релевантности: http://stackoverflow.com/questions/27140860/count-occurrences-of-number-by-column-in-pandas-data-frame – dbliss

ответ

1

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

test['score_normalized'] = test.groupby('id', group_keys=False).apply(
    lambda g: g['score']/len(g) 
) 

test 
Out[9]: 
    id  score score_normalized 
4 1 0.875933   0.291978 
5 1 0.357817   0.119272 
6 1 0.500995   0.166998 
3 2 0.958139   0.319380 
7 2 0.683463   0.227821 
9 2 0.370251   0.123417 
2 3 0.801872   0.801872 
0 4 0.272593   0.090864 
1 4 0.276464   0.092155 
8 4 0.712702   0.237567 
1

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

counts = test.groupby("id").count() 
test["score/id.size"] = test.apply(lambda x: x["score"]/float(counts[counts.index==x["id"]].score), axis=1) 

test 
    id  score score/id.size 
4 1 0.875933  0.291978 
5 1 0.357817  0.119272 
6 1 0.500995  0.166998 
3 2 0.958139  0.319380 
7 2 0.683463  0.227821 
9 2 0.370251  0.123417 
2 3 0.801872  0.801872 
0 4 0.272593  0.090864 
1 4 0.276464  0.092155 
8 4 0.712702  0.237567 
+0

Ваша метка столбца инвертирована - он запрашивает «score/id.size», а не 'id/score' (но ваши значения верны). – dbliss

+1

Исправлено. Он прокомментировал, когда я отвечал :) –

1

Это сделает работу:

test['score/id.size'] = test.score/[(test.id == i).sum() for i in test.id] 
1

Если вы хотите добавить вычисляемый столбец из groupby следует использовать transform:

In [116]: 

np.random.seed(1234) 
test = pd.DataFrame({'id':np.random.randint(1,5,10), 
        'score':np.random.uniform(0,1,10)}) 
​ 
test = test.sort(['id']) 
test 
Out[116]: 
    id  score 
4 1 0.875933 
5 1 0.357817 
6 1 0.500995 
3 2 0.958139 
7 2 0.683463 
9 2 0.370251 
2 3 0.801872 
0 4 0.272593 
1 4 0.276464 
8 4 0.712702 
In [117]: 

test['score/id.size'] = test.groupby('id')['score'].transform(lambda x: x/x.count()) 
test 
Out[117]: 
    id  score score/id.size 
4 1 0.875933  0.291978 
5 1 0.357817  0.119272 
6 1 0.500995  0.166998 
3 2 0.958139  0.319380 
7 2 0.683463  0.227821 
9 2 0.370251  0.123417 
2 3 0.801872  0.801872 
0 4 0.272593  0.090864 
1 4 0.276464  0.092155 
8 4 0.712702  0.237567 

transform возвращает серию выровненный с оригиналом ДФ

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