Перестройка pandas DataFrame
Есть датафрейм типа:
name1|name2|contact|
-------------------
a | b | 3 |
a | c | 4 |
a | d | 3 |
b | d | 1 |
b | c | 2 |
c | d | 5 |
Можно заметить, что все элементы имеют какой-то контакт друг с другом, однако они не повторяются, т.е. существует, например, строчка a | b | 3 | и нет строки b | a | 3 |. Подскажите, как можно ее сделать? Может, есть какой-то элегантный способ в стиле pandas?
Выход должен быть таким:
name1|name2|contact|
-------------------
a | b | 3 |
a | c | 4 |
a | d | 3 |
b | a | 3 |
b | d | 1 |
b | c | 2 |
c | a | 4 |
c | b | 2 |
c | d | 5 |
d | a | 3 |
d | b | 1 |
d | c | 5 |
Ответы (2 шт):
Выбираем матрицу имен (первые два столбца DF) и сортируем ее по столбцам два раза
- один раз в алфавитном порядке, второй раз в обратном. Создаем из отсортированной матрицы DataFrame, добавляем столбец с contact и объединяем два полученных DataFrame'а.
Пример:
names = df[['name1','name2']].to_numpy()
res = pd.concat([
pd.DataFrame(np.sort(names, axis=1), columns=df.columns[:2],
index=df.index)
.assign(contact=df["contact"]),
pd.DataFrame(np.sort(names, axis=1)[:, ::-1], columns=df.columns[:2],
index=df.index)
.assign(contact=df["contact"])
])
результат:
In [72]: res
Out[72]:
name1 name2 contact
0 a b 3
1 a c 4
2 a d 3
3 b d 1
4 b c 2
5 c d 5
0 b a 3
1 c a 4
2 d a 3
3 d b 1
4 c b 2
5 d c 5
На скорую руку пока только такое решение приходит:
Исходный df:
name1 name2 contact
0 a b 3
1 a c 4
2 a d 3
3 b d 1
4 b c 2
5 c d 5
решение:
df2=df.copy()
df2.columns=['name2', 'name1', 'contact']
res = pd.concat([df, df2]).sort_values(['name1','name2'])
Получаем:
name1 name2 contact
0 a b 3
1 a c 4
2 a d 3
0 b a 3
4 b c 2
3 b d 1
1 c a 4
4 c b 2
5 c d 5
2 d a 3
3 d b 1
5 d c 5