Python - по столбцам сохранить первое уникальное значение - PullRequest
0 голосов
/ 06 сентября 2018

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

Таким образом, для данной строки мне нужно только одно значение '1', но я хочу, чтобы оно сохранялось на самом высоком уровне, на котором оно было найдено.

Для этой строки: 1,1,0, я бы хотел, чтобы строка была изменена на 1,0,0

и этот ряд: 0,1,1, я бы хотел, чтобы строка была изменена на 0,1,0

Вот пример того, как могут выглядеть данные, и ожидаемый результат:

import pandas as pd

#input data
df = pd.DataFrame({'id':[1,2,3,4,5],
                   'level1':[0,0,0,0,1],
                   'level2':[1,0,1,0,1],
                   'level3':[0,1,1,1,0]})

#expected output:
new_df = pd.DataFrame({'id':[1,2,3,4,5],
                   'level1':[0,0,0,0,1],
                   'level2':[1,0,1,0,0],
                   'level3':[0,1,0,1,0]})

Ответы [ 4 ]

0 голосов
/ 06 сентября 2018

Вы можете использовать get_dummies(), присвоив 1 максимальному индексу

df[df.filter(like='level').columns] = pd.get_dummies(df.filter(like='level').idxmax(1))

   id  level1  level2  level3
0   1       0       1       0
1   2       0       0       1
2   3       0       1       0
3   4       0       0       1
4   5       1       0       0
0 голосов
/ 06 сентября 2018

Вы можете использовать расширенную индексацию с NumPy. Обновление базового массива NumPy работает здесь, поскольку у вас есть кадр данных int dtype.

idx = df.iloc[:, 1:].eq(1).values.argmax(1)
df.iloc[:, 1:] = 0
df.values[np.arange(df.shape[0]), idx+1] = 1

print(df)

   id  level1  level2  level3
0   1       0       1       0
1   2       0       0       1
2   3       0       1       0
3   4       0       0       1
4   5       1       0       0
0 голосов
/ 06 сентября 2018

numpy.eye

v = df.iloc[:, 1:].values
i = np.eye(3, dtype=np.int64)
a = v.argmax(1)
df.iloc[:, 1:] = i[a]
df

   id  level1  level2  level3
0   1       0       1       0
1   2       0       0       1
2   3       0       1       0
3   4       0       0       1
4   5       1       0       0

cumsum и mask

df.set_index('id').pipe(
    lambda d: d.mask(d.cumsum(1) > 1, 0)
).reset_index()

   id  level1  level2  level3
0   1       0       1       0
1   2       0       0       1
2   3       0       1       0
3   4       0       0       1
4   5       1       0       0
0 голосов
/ 06 сентября 2018

Использование numpy.zeros и заполнение через numpy.argmax:

out = np.zeros(df.iloc[:, 1:].shape, dtype=int)
out[np.arange(len(out)), np.argmax(df.iloc[:, 1:].values, 1)] = 1
df.iloc[:, 1:] = out

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

a = df.iloc[:, 1:].values
df.iloc[:, 1:] = (a.argmax(axis=1)[:,None] == range(a.shape[1])).astype(int)

Оба производят:

   id  level1  level2  level3
0   1       0       1       0
1   2       0       0       1
2   3       0       1       0
3   4       0       0       1
4   5       1       0       0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...