Сортировка столбца буквенно-цифровых c pandas с декадами в порядке возрастания - PullRequest
0 голосов
/ 14 июля 2020

У меня есть фрейм данных с буквенно-цифровыми c столбцами. Я хотел бы отсортировать их в порядке возрастания:

    Answer-1    Answer0     Answer1     Answer10    Answer100   Answer101   Answer102   Answer103   Answer104   Answer105   ...     Answer98    Answer99    Answers     QID     QType   Questions   Section     Theme   Topics  URL
2649    10+     NaN     1   10  NaN     NaN     NaN     NaN     NaN     NaN     ...     NaN     NaN     ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']    1048    Likert Scale    How many times do you usually travel via airplane in a year     What changes would you like to see on your flight in the future? If any.    Airline XYZ     ['time', 'usual', 'travel', 'airplan', 'year']  https://docs.google.com/forms/d/1qQ28JBZE-8Mk-4wfCNfejz-_2AGKLWPUIBuzhsFE-kg/edit?usp=sharing
4155    5 or more   NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     ...     NaN     NaN     ['012345']  2906    Likert Scale    How many flights were cancelled/affected by the global lockdown?    Media consumption   Airline XYZ     ['flight', 'cancel', 'affect', 'global', 'lockdown']    https://docs.google.com/forms/d/1yPWGOPVpk2HEj7M-2XbJDdm3EvmRozos-upH7wI9VvY/edit?usp=sharing
...

Я уже кое-что пробовал, в результате получилось то, что вы видите выше, но, похоже, проблема с десятками:

df_merged[df_merged['QType'] == 'Likert Scale'].sort_values(by='Answer0', ascending=True)

Обновление

Я попробовал ответить YOLO:

# create mapping of name to index
idx = dict(enumerate(df_merged.columns))

# extract digits
idx = {k: re.sub(r'\D', '', v) for k,v in idx.items()}

idx = list(dict(sorted(idx.items(), key=lambda x: int(x[1]))).keys())

df_merged = df_merged.iloc[:,idx]

Но получил:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-874-9a2435876ebe> in <module>
      7 idx = {k: re.sub(r'\D', '', v) for k,v in idx.items()}
      8 
----> 9 idx = list(dict(sorted(idx.items(), key=lambda x: int(x[1]))).keys())
     10 
     11 df_merged = df_merged.iloc[:,idx]

<ipython-input-874-9a2435876ebe> in <lambda>(x)
      7 idx = {k: re.sub(r'\D', '', v) for k,v in idx.items()}
      8 
----> 9 idx = list(dict(sorted(idx.items(), key=lambda x: int(x[1]))).keys())
     10 
     11 df_merged = df_merged.iloc[:,idx]

ValueError: invalid literal for int() with base 10: ''

Меня также беспокоят последние несколько столбцов которые не похожи на AnswerXYZ (XYZ - числа).

Я также тестирую эту идею:

import re

def convertir(nombre):
  m = re.match(r"Answer(-?\d+)", nombre)
  if m:
    return ("Answer", int(m.groups(1)[0]))
  return (nombre, 0)

nombres = ['Answer-1', 'Answer0', 'Answer1', 'Answer10', 'Answer100',
     'Answer101', 'Answer102', 'Answer103', 'Answer104', 'Answer105',
     'Answer98', 'Answer99', 'Answers', 'QID', 'QType', 'Questions',
     'Section', 'Theme', 'Topics', 'URL']

print(sorted(nombres, key=convertir))

Кажется, он работает, но Я не знаю, как использовать вывод sorted(nombres, key=convertir) для сортировки столбцов фрейма данных.

1 Ответ

1 голос
/ 14 июля 2020

Нам нужно создать сопоставление имен столбцов с их индексом в фрейме данных. Вы можете сделать:

# create mapping of name to index
idx = dict(enumerate(df.columns))

# extract digits
idx = {k: re.sub(r'\D', '', v) for k,v in idx.items()}

# sort digits and keep its corresponding index
idx = list(dict(sorted(idx.items(), key=lambda x: int(x[1]))).keys())

df = df.iloc[:,idx]
 
print(df.head())

    Answer0   Answer1   Answer2   Answer3   Answer4   Answer5   Answer6
0  0.652074  0.334795  0.309215  0.489695  0.011754  0.908632  0.395250   
1  0.281704  0.169817  0.683343  0.891602  0.208878  0.029028  0.519839   
2  0.983723  0.067707  0.053501  0.712321  0.224386  0.609682  0.323190   
3  0.557681  0.484641  0.053048  0.134786  0.609206  0.378064  0.540113   
4  0.031538  0.675454  0.556284  0.384275  0.731091  0.298495  0.952463

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

import numpy as np

cols = [f"Answer{x}" for x in range(20)]
np.random.shuffle(cols)
df = pd.DataFrame(np.random.random((10, 20)), columns=cols)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...