2015-09-24 4 views
1

В мультииндексированном кадре данных pandas, как установить значения в столбце, которые полагаются на определенное условие, содержащееся в другом столбце?Условно заменить данные в мультииндексированном фрейме pandas

Итак, у меня есть dataframe, что по существу выглядит следующим образом:

  COL1  COL2  COL3  COL4 
foo 1 -1.322275 1.107506 1.253344 -0.331782 
    2 -0.378448 -1.174557 -0.772984 1.476661 
    3 0.046396 0.904299 0.768654 -0.168910 
    4 1.396580 1.250713 0.193130 -0.454971 
bar 1 -1.453794 -0.393206 -0.922908 0.762605 
    2 1.375954 -1.304682 0.329339 0.606340 
    3 -2.911151 0.011083 0.771964 1.620039 
    4 0.040204 0.887082 -0.893575 1.129227 

Вы можете создать с помощью этого кода:

arrays = [np.array(['foo','foo','foo','foo','bar','bar','bar','bar']), 
      np.array([1,2,3,4,1,2,3,4])] 
df = pd.DataFrame(np.random.randn(8,4), index=arrays) 
df.columns = ['COL1','COL2','COL3','COL4'] 

Я хочу, чтобы оценить 'COL1', подрамник «Foo 'для значений больше 0 и заменить (не на месте) значения «COL4» для соответствующих строк с новым значением COL1/1. Затем я хотел бы сделать то же самое снова для subframe «bar», однако вместо этого оценивайте значения «COL2».

Моя фактическая датафрейма огромна, поэтому я пытаюсь найти лучшее решение, чем повторять по строкам. Я смог условно заменить обычный фреймворк данных, но что-то не щелкает, когда я пытаюсь выполнить более продвинутую многоиндексировку и настройку. Я, наверное, делаю вещи более сложными, но я около 45 минут от зарядки стены.

+0

Я не получаю то, что вы меня и 'COL1/1'. Какое значение у вас для COL4 для индекса [foo] [3]? И когда вы оцениваете COL2, вы хотите снова заменить значения COL4? – vmg

ответ

0

Я не совсем понял, что вы хотите заменить в своей колонке «цель», поэтому я сделал нечто общее. Вы можете заменить бит по мере необходимости.

Вот определение:

def repfunc(row,evalcol,replacecol): 
    if row[evalcol] > 0: 
     row[replacecol] = 999 #replace value goes here! 
    return row 

def repframe(df,repindex,evalcol,replacecol): 
    df.sort_index(inplace=True) 
    df.loc[repindex][replacecol] = df.loc[repindex].apply(lambda x: repfunc(x,evalcol,replacecol), axis=1).loc[:,replacecol] 

А вот как вы это называете:

repframe(df,'foo','COL1','COL4') 

Вы можете заменить параметры повторить операцию в другом срезе/столбцов dataframe, по мере необходимости , Вышеописанная операция изменяет dataframe так:

  COL1  COL2  COL3  COL4 
foo 1 1.436672 0.213772 -0.705179 -1.297816 
    2 -0.995535 -0.067389 0.290504 -0.794496 
    3 1.375566 0.271896 -0.577298 -1.450002 
    4 -0.603792 -0.450790 -1.484757 1.401513 
bar 1 0.975558 -0.645254 -0.760839 -0.629055 
    2 -1.972025 -0.108141 1.317623 0.126768 
    3 1.947666 1.270041 -0.034555 -1.540862 
    4 -3.124269 0.176528 1.815705 0.299059 

В это:

  COL1  COL2  COL3  COL4 
bar 1 0.975558 -0.645254 -0.760839 -0.629055 
    2 -1.972025 -0.108141 1.317623 0.126768 
    3 1.947666 1.270041 -0.034555 -1.540862 
    4 -3.124269 0.176528 1.815705 0.299059 
foo 1 1.436672 0.213772 -0.705179 999.000000 
    2 -0.995535 -0.067389 0.290504 -0.794496 
    3 1.375566 0.271896 -0.577298 999.000000 
    4 -0.603792 -0.450790 -1.484757 1.401513 

Я думаю, у вас были проблемы с сбросом столбца dataframe с мультииндексом, потому что мультииндекс должен быть отсортирован для операций в возвращать представления (а не копии) данных. Это necessary if you want to perform this kind of replacement in multiindexed dataframes, насколько я знаю. Обратите внимание, что repframe звонит sort_index с inplace=True.

Моя версия всегда заменяет положительные значения на 999. Она «применяется» по строкам, но я не могу понять, как вы могли бы это сделать без этого.

+0

Ты Рок! Вы определенно указали мне на правильный путь. Ваша версия работает, однако она по-прежнему бросает эту глупую точку зрения против ошибки копирования. (Я использую pandas0.15.2) Является ли ошибка помечена, потому что lambda isdecoupling .loc в repframe? – crashMOGWAI

+0

Я хочу сделать что-то вроде этой строки [replacecol] = (row [evalcol])/5' с 'repfunc()', но у меня все еще есть проблемы. – crashMOGWAI

+0

Спасибо. Приятно было знать, что это сработало. Я не знаю об этом сообщении - я использую ту же самую версию pandas. Это просто предупреждение? – vmg

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