обновить несколько столбцов pandas кадра данных, используя np.where или loc - PullRequest
1 голос
/ 12 января 2020

У нас есть фрейм данных:

data = [['A1', 'B1'], ['A2', 'B2', 1, 2], ['A3', 'B3', 3, 4], ['A4', 'B4']]
df = pd.DataFrame(data, columns=['A','B','C','D'])

, который выглядит следующим образом

A  | B  | C   | D
-------------------
A1 | B1 | NaN | NaN
A2 | B2 | 1   | 2
A3 | B3 | 3   | 4
A4 | B4 | Nan | NaN
-------------------

для столбцов C и D, они оба будут заполнены или оба будут NaN (не будет сценария, в котором C равен NaN, а D будет иметь значения или наоборот)

Моя цель состоит в том, чтобы преобразовать фрейм данных так:

A  | B  | C   | D
-------------------
A1 | B1 | NaN | NaN
1  | 2  | 1   | 2
3  | 4  | 3   | 4
A4 | B4 | Nan | NaN
-------------------

Я попытался

df.loc[df['C'].notna(), ['A', 'B']] = df.loc[df['C'].notna(), ['C', 'D']]
# the above just assigns back NaN values instead of 1,2,3,4 

и

m = df['C'].notna()
df[['A', 'B']] = np.where(m, df[['C', 'D']], df[['A', 'B']])
# the above errors with operands could not be broadcast together with shapes (4,) (4,2) (4,2) 
df[['X', 'Y']] = pd.DataFrame(np.where(m, df[['C', 'D']]), df[['A', 'B']])
# the above errors with ValueError: either both or neither of X and Y should be given

Я рассмотрел этот вопрос здесь и попробовал несколько способов преобразования df[['C', 'D']] в списки и назначить его обратно как новый фрейм данных, но я все еще не смог заставить его работать.

Я знаю, что могу назначить столбцы (A- C, BD) индивидуально, но я имею дело с большим количество таких пар и хотите избежать их зацикливания. Есть ли чистый способ выполнить эту операцию за один проход?

с использованием pandas версии 0.25.3.

Спасибо за помощь!

Ответы [ 2 ]

2 голосов
/ 12 января 2020

Использование pandas.loc[...]:

df.loc[~df['C'].isna(), 'A']=df.loc[~df['C'].isna(), 'C']
df.loc[~df['D'].isna(), 'B']=df.loc[~df['D'].isna(), 'D']

Использование np.where(...):

import numpy as np

df[['A', 'B']]=np.where(df['C'].notna().to_numpy().reshape(-1,1), df[['C', 'D']], df[['A', 'B']])

Вывод:

    A   B    C    D
0  A1  B1  NaN  NaN
1   1   2  1.0  2.0
2   3   4  3.0  4.0
3  A4  B4  NaN  NaN
2 голосов
/ 12 января 2020

Попробуйте получить значения для назначения, а именно:

import pandas as pd

data = [['A1', 'B1'], ['A2', 'B2', 1, 2], ['A3', 'B3', 3, 4], ['A4', 'B4']]
df = pd.DataFrame(data, columns=['A','B','C','D'])

df.loc[df['C'].notna(), ['A','B']] = df.loc[df['C'].notna(), ['C','D']].to_numpy()

df

    A   B    C    D
0  A1  B1  NaN  NaN
1   1   2  1.0  2.0
2   3   4  3.0  4.0
3  A4  B4  NaN  NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...