2016-10-20 4 views
1

У меня есть существующий панды Dataframe в следующем формате:значения Обновление в панд dataframe, используя другой dataframe

sample_dict = {'ID': [100, 200, 300], 'a': [1, 2, 3], 'b': [.1, .2, .3], 'c': [4, 5, 6], 'd': [.4, .5, .6]} 
df_sample = pd.DataFrame(sample_dict) 

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

sample_update = {'ID': [100, 300], 'a': [3, 2], 'b': [.4, .2], 'c': [2, 5], 'd': [.7, .1]} 
df_updater = pd.DataFrame(sample_update) 

правило для обновления заключается в следующем:

  1. для столбца a и c, просто добавьте значения от a и c в df_updater.
  2. Для столбца b это зависит от обновленного значения a. Предположим, что функция обновления будет b = old_b + (new_b/updated_a).
  3. Для столбца d правила аналогичны правилам столбца b, за исключением того, что они зависят от значений обновленных c и new_d.

Вот желаемый результат:

new = {'ID': [100, 200, 300], 'a': [4, 2, 5], 'b': [.233333, .2, .33999999], 'c': [6, 5, 11], 'd': [.51666666, .5, .609090]} 
df_new = pd.DataFrame(new) 

Мои актуальные проблемы используют несколько более сложную версию этого, но я думаю, что этот пример достаточно, чтобы решить мою проблему. Кроме того, в моем реальном DataFrame у меня больше столбцов, следующих по тем же правилам, поэтому я хотел бы, чтобы этот метод мог перебирать столбцы, если это возможно. Благодаря!

+0

Вы можете добавить необходимые dataframe для облегчения проверочных решений? – jezrael

+0

хорошо, я добавлю это. – jtitusj

+0

И один вопрос - значения «ID» уникальны? – jezrael

ответ

1

Вы можете использовать функции merge, add и div:

df = pd.merge(df_sample,df_updater,on='ID', how='left') 

df[['a','c']] = df[['a_y','c_y']].add(df[['a_x','c_x']].values, fill_value=0) 

df['b'] = df['b_x'].add(df['b_y'].div(df.a_y), fill_value=0) 
df['d'] = df['c_x'].add(df['d_y'].div(df.c_y), fill_value=0) 
print (df) 
    ID a_x b_x c_x d_x a_y b_y c_y d_y a  c   b  d 
0 100 1 0.1 4 0.4 3.0 0.4 2.0 0.7 4.0 6.0 0.233333 4.35 
1 200 2 0.2 5 0.5 NaN NaN NaN NaN 2.0 5.0 0.200000 5.00 
2 300 3 0.3 6 0.6 2.0 0.2 5.0 0.1 5.0 11.0 0.400000 6.02 

print (df[['a','b','c','d']]) 
    a   b  c  d 
0 4.0 0.233333 6.0 4.35 
1 2.0 0.200000 5.0 5.00 
2 5.0 0.400000 11.0 6.02 

Вместо merge Возможное использование concat:

df=pd.concat([df_sample.set_index('ID'),df_updater.set_index('ID')], axis=1,keys=('_x','_y')) 
df.columns = [''.join((col[1], col[0])) for col in df.columns] 
df.reset_index(inplace=True) 
print (df) 
    ID a_x b_x c_x d_x a_y b_y c_y d_y 
0 100 1 0.1 4 0.4 3.0 0.4 2.0 0.7 
1 200 2 0.2 5 0.5 NaN NaN NaN NaN 
2 300 3 0.3 6 0.6 2.0 0.2 5.0 0.1 
+0

Проверьте значения в столбце 'd' - что такое формула обновления? 'old_c + (new_d/updated_c)'? – jezrael

+0

yep. Это верно. Насколько эффективен этот метод? Я думаю, что это создаст много ненужных столбцов и может замедлить вычисления. – jtitusj

+0

Проблема заключается в том, что вам нужно выровнять оба фрейма данных с помощью идентификатора '' ', поэтому сначала нужно выполнить' merge' или 'concat', а затем выполнить арифметические операции. – jezrael

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