Сортировка фрейма данных Pandas путем сопоставления нескольких строк

#python #pandas #sorting

#python #pandas #сортировка

Вопрос:

Предположим, у меня есть такой фрейм данных:

 data=np.array([[-1.5625e-05,-1.5625e-05,-4.6875e-05],
[-1.5625e-05,-1.5625e-05,-1.5625e-05],
[-1.5625e-05,1.5625e-05,-4.6875e-05],
[-1.5625e-05,1.5625e-05,-1.5625e-05],
[1.5625e-05,-1.5625e-05,-4.6875e-05],
[1.5625e-05,-1.5625e-05,-1.5625e-05],
[1.5625e-05,1.5625e-05,-4.6875e-05],
[1.5625e-05,1.5625e-05,-1.5625e-05]])

df=pd.DataFrame(data=data,columns=['x','y','z'])
 

и массив numpy

 coord=np.array([[-1.5625e-05,-1.5625e-05,-4.6875e-05],
[-1.5625e-05,1.5625e-05,-4.6875e-05],
[1.5625e-05,-1.5625e-05,-4.6875e-05],
[1.5625e-05,1.5625e-05,-4.6875e-05],
[-1.5625e-05,-1.5625e-05,-1.5625e-05],
[-1.5625e-05,1.5625e-05,-1.5625e-05],
[1.5625e-05,-1.5625e-05,-1.5625e-05],
[1.5625e-05,1.5625e-05,-1.5625e-05]])
 

Количество строк в фрейме данных Pandas и массиве координат всегда одинаковы. Как вы можете видеть, строки между фреймом данных Pandas и координацией одинаковы, но в другом порядке. Я хотел бы отсортировать фрейм данных в соответствии с порядком массива координат (например, df.x==coord[:,0] amp; df.y==coord[:,1] amp; df.z ==coord[:,2]).

Комментарии:

1. Что произойдет, если у вас есть дубликаты координат?

2. Я не уверен, как это будет работать. Но большая часть непосредственного набора данных, с которым я имею дело, все координаты уникальны.

Ответ №1:

вы могли бы сделать это так:

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

код

 df2 = pd.DataFrame(coord, columns=list("xyz"))
sort_cols = list("yxz")
df = df.sort_values(sort_cols)
df2 = df2.sort_values(sort_cols)
df.index = df2.index
df = df.sort_index()
 

Это должно возвращать df, отсортированное как coord (output):

           x         y         z
0 -0.000016 -0.000016 -0.000047
1 -0.000016  0.000016 -0.000047
2  0.000016 -0.000016 -0.000047
3  0.000016  0.000016 -0.000047
4 -0.000016 -0.000016 -0.000016
5 -0.000016  0.000016 -0.000016
6  0.000016 -0.000016 -0.000016
7  0.000016  0.000016 -0.000016
 

Комментарии:

1. Я должен сказать: очевидно, было бы проще просто создать фрейм данных из координаты. Если это возможно для вашей проблемы, было бы проще / эффективнее

2. Да, я согласен! Особенно для некоторых наборов данных, которые я обрабатываю, может содержать до миллионов строк. Проблема, с которой я сталкиваюсь, заключается в том, что фрейм данных и массив координат генерируются двумя разными программами. Я только что выяснил, что массив координат сортируется по z, x, y в порядке возрастания. Проблема сейчас в том, что я не уверен, всегда ли это будет правдой.

3. хм… возможно, вам лучше просто отсортировать все данные (включая numpy) по x, y, z, а не выполнять сопоставление индексов. Я думаю, что это соответствует другому ответу

Ответ №2:

Вы можете выполнить требуемую сортировку с помощью:

 df.sort_values(['x', 'y', 'z'], ascending=[True, True, True])
 

Полный код:

 import numpy as np
import pandas as pd

data=np.array([[-1.5625e-05,-1.5625e-05,-4.6875e-05],
[-1.5625e-05,-1.5625e-05,-1.5625e-05],
[-1.5625e-05,1.5625e-05,-4.6875e-05],
[-1.5625e-05,1.5625e-05,-1.5625e-05],
[1.5625e-05,-1.5625e-05,-4.6875e-05],
[1.5625e-05,-1.5625e-05,-1.5625e-05],
[1.5625e-05,1.5625e-05,-4.6875e-05],
[1.5625e-05,1.5625e-05,-1.5625e-05]])

df= pd.DataFrame(data=data,columns=['x','y','z'])

df.sort_values(['x', 'y', 'z'], ascending=[True, True, True])

print(df)
 

вывод:

           x         y         z
0 -0.000016 -0.000016 -0.000047
1 -0.000016 -0.000016 -0.000016
2 -0.000016  0.000016 -0.000047
3 -0.000016  0.000016 -0.000016
4  0.000016 -0.000016 -0.000047
5  0.000016 -0.000016 -0.000016
6  0.000016  0.000016 -0.000047
7  0.000016  0.000016 -0.000016
 

Комментарии:

1. Спасибо за ваш ответ. Я только что попробовал. Это не сработало. Основная проблема заключается в том, что массив координат генерируется случайным образом и не следует никакому шаблону.

2. Я проверил его с помощью вашего массива, и это удалось.

3. Первая строка отсортированного фрейма данных совпадает, но вторая строка нет: [-0.000016, -0.000016, -0.000016] против [-1.5625e-05,1.5625e-05,-4.6875e-05]

4. во-первых, он сортируется на основе x, и если x повторяется, он сортируется в соответствии с y, а если y повторяется, он сортируется в соответствии с z и (-0.000047 < -0.000016) при сравнении row1 и row2

5. Я просто проверяю еще раз на основе вашего последнего комментария. Ваш ответ был почти готов. Если вы измените порядок сортировки на df.sort_values([‘z’, ‘x’, ‘y’], по возрастанию =[True, True, True]), то ответ будет совпадать. Опять же, моя проблема в том, что я не могу гарантировать, что сгенерированный массив координат будет предварительно отсортирован в этом точном порядке (z, x, y). Спасибо за вашу помощь!