Панды - Заменить другие столбцы в строке на 0, если конкретный столбец имеет значение 1 - PullRequest
0 голосов
/ 04 ноября 2018

Вот пример кадра данных:

X Y Z 
1 0 1
0 1 0
1 1 1

Теперь вот правило, которое я придумал:

  • Х осталось как есть
  • Если Y равно 1, установить соответствующее значение в X равным 0
  • Если Z равно 1, установить соответствующее значение в X и Y равным 0

Конечный кадр данных должен выглядеть следующим образом:

X Y Z 
0 0 1
0 1 0
0 0 1

Моя первая мысль о решении такова:

df_null_list = ['X']

for i in ['Y', 'Z']:

    df[df[i] == 1][df_null_list] = 0

    df_null_list.append(i)

Когда я делаю это и суммирую по оси y, я начинаю получать значения 2 и 4, которые не имеют смысла. Обратите внимание, я имею в виду, когда я запустил это на фактическом наборе данных.

У вас есть предложения по улучшению или альтернативным решениям?

Ответы [ 3 ]

0 голосов
/ 04 ноября 2018

Вы можете обобщить это так, чтобы последний индекс 1 на строку оставался 1, а все остальное оставлялось как 0. Для повышения производительности работайте с базовым массивом numpy:

a = df.values
idx = (a.shape[1] - a[:, ::-1].argmax(1)) - 1
t = np.zeros(a.shape)
t[np.arange(a.shape[0]), idx] = 1

array([[0., 0., 1.],
       [0., 1., 0.],
       [0., 0., 1.]])

Если вам нужен результат как DataFrame:

pd.DataFrame(t, columns=df.columns, index=df.index).astype(int)

   X  Y  Z
0  0  0  1
1  0  1  0
2  0  0  1
0 голосов
/ 04 ноября 2018

Другое решение может заключаться в выполнении операции расширения на оси строк, используя numpy:

df1 = df.copy() == 1
df1.iloc[:,::-1].expanding(axis=1).apply(
                 lambda x: x[-1] * np.prod(np.logical_not(x[:-1]))
                 ).iloc[:,::-1]

     X    Y    Z
0  0.0  0.0  1.0
1  0.0  1.0  0.0
2  0.0  0.0  1.0
0 голосов
/ 04 ноября 2018

Использование mask:

df['X'] = df['X'].mask(df.Y == 1, 0)
df[['X', 'Y']] = df[['X', 'Y']].mask(df.Z == 1, 0)

Другое решение с DataFrame.loc:

df.loc[df.Y == 1, 'X'] = 0
df.loc[df.Z == 1, ['X', 'Y']] = 0

print (df)
   X  Y  Z
0  0  0  1
1  0  1  0
2  0  0  1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...