Сводная таблица для «аккуратного» фрейма данных в Pandas - PullRequest
2 голосов
/ 05 февраля 2020

У меня есть массив чисел (я думаю, что формат делает его сводной таблицей), который я хочу превратить в «аккуратный» фрейм данных. Например, я начинаю с переменной 1 внизу слева, переменной 2 сверху и значения интереса в середине, что-то вроде этого:

  X Y
A 1 2
B 3 4

Я хочу превратить это в аккуратный фрейм данных например:

V1 V2 value
A  X    1
A  Y    2
B  X    3
B  Y    4

Порядок строк и столбцов для меня не имеет значения, поэтому вполне приемлемо следующее:

value V1 V2
  2    A  Y
  4    B  Y
  3    B  X
  1    A  X

Для моих первых go при этом, что удалось получить мне правильный окончательный ответ, я перебрал строки и столбцы. Это было ужасно медленно, и я подозревал, что некоторые машины в Pandas сделают его go быстрее.

Кажется, что melt близко к магу c Я ищу, но это не дает мне пройти весь путь туда. Этот первый массив превращается в такой:

   V2 value
0  X    1
1  X    2
2  Y    3
3  Y    4

Он избавляется от моей переменной V1!

Ничего особенного в melt нет, поэтому я буду рад прочитать ответы, использующие другие подходы особенно если melt не намного быстрее, чем мои вложенные циклы, и есть другое решение. Тем не менее, как я могу go из этого массива в вид аккуратного фрейма данных, который я хочу в качестве вывода?

Пример кадра данных:

df = pd.DataFrame({"X":[1,3], "Y":[2,4]},index=["A","B"])

Ответы [ 2 ]

5 голосов
/ 05 февраля 2020

Используйте DataFrame.reset_index с DataFrame.rename_axis , а затем DataFrame.melt. Если вы хотите заказать столбцы, мы можем использовать DataFrame.reindex.

new_df = (df.rename_axis(index = 'V1')
            .reset_index()
            .melt('V1',var_name='V2')
            .reindex(columns = ['value','V1','V2']))
print(new_df)

Другой подход DataFrame.stack:

new_df = (df.stack()
            .rename_axis(index = ['V1','V2'])
            .rename('value')
            .reset_index()
            .reindex(columns = ['value','V1','V2']))
print(new_df)

   value V1 V2
0      1  A  X
1      3  B  X
2      2  A  Y
3      4  B  Y

именам имен есть другая альтернатива, такая как комментирование @ Скотт Бостон в комментариях

2 голосов
/ 05 февраля 2020

Расплав - это хороший подход, но, похоже, он не очень подходит для определения результатов по индексу. Вы можете сначала сбросить индекс, чтобы переместить его в свой собственный столбец, а затем использовать этот столбец в качестве идентификатора столбца.

test = pd.DataFrame([[1,2],[3,4]], columns=['X', 'Y'], index=['A', 'B'])
   X  Y
A  1  2
B  3  4

test = test.reset_index()
  index  X  Y
0     A  1  2
1     B  3  4

test.melt('index',['X', 'Y'], 'prev cols')  
  index prev cols  value
0     A         X      1
1     B         X      3
2     A         Y      2
3     B         Y      4
...