2017-01-31 5 views
1

У меня есть dataframe (df) с 10 столбцами. Индекс имеет много разных дат, однако есть несколько идентичных дат (и сортируется по дате). Кроме того, важными столбцами для этой проблемы являются df ['Weight'] и df ['Test'].Создание нового столбца на основе корректировки весов из других столбцов

Вот пример данных с 2-мя колонками только 1 значение индекса (1/21/2017), на самом деле есть несколько дат с несколькими весами и т.д.

  Weight Test 
1/21/2017 0.1  NaN 
1/21/2017 0.04 0.04 
1/21/2017 0.03 Nan 
1/21/2017 0.02 Nan 
1/21/2017 0.2  0.2 
1/21/2017 0.001 Nan 
1/21/2017 0.1  0.1 
1/21/2017 0.21 0.21 
1/21/2017 0.003 Nan 
1/21/2017 0.01 0.01 
1/21/2017 0.04 0.04 
1/21/2017 0.005 Nan 
1/21/2017 0.05 0.05 
1/21/2017 0.1  Nan 
1/21/2017 0.091 Nan 

ФР [ 'Вес '] добавляет до 1 для определенного индекса, и это верно для каждой уникальной даты индекса.

Я создал тестовую колонку, которая показывает только вес, если условие выполнено.

Теперь я пытаюсь создать столбец df ['скорректированный вес "], который будет смотреться в столбце Test, и если есть Nan, он умножит вес, который находится в df [' Weight '], на 0,75 и назначит это к df ['adjust_weight'], а затем остальные записи, в которых df ['Test'] не нан для конкретной даты, весы df ['Test'] должны корректироваться вверх пропорционально и присваиваться df [' скорректированный вес '], поэтому сумма df [' скорректированный вес '] для любой даты = 1.

Я хотел бы быть гибким, так что я могу также умножать весов на 0,5 и 0,75 и пропорциональном сделано для отдыха и т.д.

Спасибо всем огромное за помощь и поддержку.

С наилучшими пожеланиями.

+0

Я не понимаю математику. 'df.Test.sum() * 2 == 1.30' Итак, вы хотите иметь отрицательные записи для тех строк, где' Test is NaN'? – MaxU

+0

Извинения, моя ошибка. Я действительно хочу, чтобы вес весом 0,75, а затем весы были скорректированы вверх. Уточнили вопрос. – MysterioProgrammer91

+0

Это поможет увидеть желаемый результат. – Parfait

ответ

1
def bool_scale(df, col, cond, scale): 
    cond = df[cond].notnull().values 
    v = df.values 
    i = df.columns.get_loc(col) 
    w = v[:, i] 
    w_up = w[cond].sum() 
    return df.assign(
     adjusted_weight=np.where(
      cond, w * scale, w/(1 - w_up) * (1 - scale * w_up))) 

bool_scale(df, 'Weight', 'Test', .75) 

      Weight Test adjusted_weight 
1/21/2017 0.100 NaN   0.146429 
1/21/2017 0.040 0.04   0.030000 
1/21/2017 0.030 NaN   0.043929 
1/21/2017 0.020 NaN   0.029286 
1/21/2017 0.200 0.20   0.150000 
1/21/2017 0.001 NaN   0.001464 
1/21/2017 0.100 0.10   0.075000 
1/21/2017 0.210 0.21   0.157500 
1/21/2017 0.003 NaN   0.004393 
1/21/2017 0.010 0.01   0.007500 
1/21/2017 0.040 0.04   0.030000 
1/21/2017 0.005 NaN   0.007321 
1/21/2017 0.050 0.05   0.037500 
1/21/2017 0.100 NaN   0.146429 
1/21/2017 0.091 NaN   0.133250 

Вы можете применить его в groupby

kws = dict(col='Weight', cond='Test', scale=.75) 
df.groupby(level=0).apply(bool_scale, **kws) 

        Weight Test adjusted_weight 
1/21/2017 1/21/2017 0.100 NaN   0.146429 
      1/21/2017 0.040 0.04   0.030000 
      1/21/2017 0.030 NaN   0.043929 
      1/21/2017 0.020 NaN   0.029286 
      1/21/2017 0.200 0.20   0.150000 
      1/21/2017 0.001 NaN   0.001464 
      1/21/2017 0.100 0.10   0.075000 
      1/21/2017 0.210 0.21   0.157500 
      1/21/2017 0.003 NaN   0.004393 
      1/21/2017 0.010 0.01   0.007500 
      1/21/2017 0.040 0.04   0.030000 
      1/21/2017 0.005 NaN   0.007321 
      1/21/2017 0.050 0.05   0.037500 
      1/21/2017 0.100 NaN   0.146429 
      1/21/2017 0.091 NaN   0.133250 
+0

Цените комментарий, да, я испортил математику. По сути, я хотел увеличить вес, когда у Теста были значения. Я изменил вопрос, чтобы дать правильную логику. Благодарю. – MysterioProgrammer91

+0

@ MysterioProgrammer91 исправлено, чтобы отразить ваши изменения – piRSquared

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