Pandas обновить сразу несколько столбцов

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

df = pd.DataFrame([['A','B','C',np.nan,np.nan,np.nan],
                  ['D','E','F',np.nan,np.nan,np.nan],[np.nan,np.nan,np.nan,'a','b','d'],
                  [np.nan,np.nan,np.nan,'d','e','f']], columns = ['Col1','Col2','Col3','col1_v2','col2_v2','col3_v2'])

print df

 Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0    A    B    C     NaN     NaN     NaN
1    D    E    F     NaN     NaN     NaN
2  NaN  NaN  NaN       a       b       d
3  NaN  NaN  NaN       d       e       f

#update 
df.loc[df['Col1'].isnull(),['Col1','Col2', 'Col3']] = df[['col1_v2','col2_v2','col3_v2']]

print df

 Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0    A    B    C     NaN     NaN     NaN
1    D    E    F     NaN     NaN     NaN
2  NaN  NaN  NaN       a       b       d
3  NaN  NaN  NaN       d       e       f

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

 Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0    A    B    C     NaN     NaN     NaN
1    D    E    F     NaN     NaN     NaN
2    a    b    c       a       b       d
3    d    e    f       d       e       f

Я уверен, что это связано с обновлением/настройкой на срезе, но я всегда использую .loc для обновления значений, а не только для нескольких столбцов одновременно.

Я чувствую, что есть простой способ сделать это, что я просто отсутствую, любые мысли/предложения будут приветствоваться!

Изменить, чтобы отразить решение ниже Спасибо за комментарий к индексам. Однако у меня есть вопрос об этом, поскольку он относится к серии. Если бы я хотел обновить отдельную серию аналогичным образом, я мог бы сделать что-то вроде этого:

df.loc[df['Col1'].isnull(),['Col1']] = df['col1_v2']

print df

  Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0    A    B    C     NaN     NaN     NaN
1    D    E    F     NaN     NaN     NaN
2    a  NaN  NaN       a       b       d
3    d  NaN  NaN       d       e       f

Обратите внимание, что здесь я не учитывал индексы, я отфильтровывался до серии 2x1 и устанавливал значение, равное серии 4x1, но он правильно его обрабатывал. Мысли? Я пытаюсь понять функциональность немного лучше того, что я использовал какое-то время, но, я думаю, не имеет полного понимания основного механизма/правила

Ответ 1

вы хотите заменить

print df.loc[df['Col1'].isnull(),['Col1','Col2', 'Col3']]

  Col1 Col2 Col3
2  NaN  NaN  NaN
3  NaN  NaN  NaN

С

replace_with_this = df.loc[df['Col1'].isnull(),['col1_v2','col2_v2', 'col3_v2']]
print replace_with_this

  col1_v2 col2_v2 col3_v2
2       a       b       d
3       d       e       f

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

Итак, это должно работать:

df.loc[df['Col1'].isnull(),['Col1','Col2', 'Col3']] = replace_with_this.values

print df

  Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0    A    B    C     NaN     NaN     NaN
1    D    E    F     NaN     NaN     NaN
2    a    b    d       a       b       d
3    d    e    f       d       e       f

Я учитывал столбцы, используя .values в конце. Это разделило информацию столбца из фрейма replace_with_this и просто использовало значения в соответствующих позициях.

Ответ 2

В духе "взять холм" я предлагаю нижеприведенное решение, которое дает требуемый результат.

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

#Does not work when indexing on np.nan, so I fill with some arbitrary value. 
df = df.fillna('AAA')

#mask to determine which rows to update
mask = df['Col1'] == 'AAA'

#dict with key value pairs for columns to be updated
mp = {'Col1':'col1_v2','Col2':'col2_v2','Col3':'col3_v2'}

#update
for k in mp: 
     df.loc[mask,k] = df[mp.get(k)]

#swap back np.nans for the arbitrary values
df = df.replace('AAA',np.nan)

Выход:

Col1    Col2    Col3    col1_v2     col2_v2     col3_v2
A       B       C       NaN         NaN         NaN
D       E       F       NaN         NaN         NaN
a       b       d       a           b           d
d       e       f       d           e           f

Ошибка, которую я получаю, если я не заменяю nans, ниже. Я собираюсь точно изучить, откуда эта ошибка.

ValueError: array is not broadcastable to correct shape