Как я могу отсортировать записи данных так, чтобы диапазон данных был сгруппирован вместе в Python или в Google Таблицах? - PullRequest
1 голос
/ 28 мая 2020

Например, учитывая набор данных с различными весами и именами, как я могу сгруппировать людей с одинаковым весом (+/- 5% от веса, который я хочу) вместе?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 июня 2020

Я понимаю, что вы хотите разделить свои данные на группы, где максимальная разница от самого большого к меньшему составляет ± 5%. Я написал код Apps Script , который может сделать это в вашем Листе. Во-первых, я написал образец листа с именами учащихся и результатами тестов (от 0 до 10) вместо имен и роста; Я объясню почему позже. Это начальное состояние листа примера:

Initial example

В столбце Group код удалит идентификатор группы как целое число, начиная с 0 Это код:

function so62060595() {
  var dataColumn = 2; // Column B
  var groupColumn = 3; // Column C
  var dataSheet = SpreadsheetApp.getActive().getActiveSheet();
  var dataRange = dataSheet.getRange(2, 1, dataSheet.getLastRow() - 1, dataSheet
    .getLastColumn()).sort({
    column: dataColumn,
    ascending: false
  });
  var data = dataRange.getValues();
  var groupingPercentage = 5 / 100 // 5%
  var upperBound = data[0][dataColumn - 1];
  var groupID = 0;

  for (var r = 0; r < data.length; r++) {
    if (upperBound - upperBound * groupingPercentage <= data[r][dataColumn -
      1] + data[r][dataColumn - 1] * groupingPercentage) {
      // Include in the same group
      data[r][groupColumn - 1] = groupID;
    } else {
      // Create a new group
      var groupID = groupID + 1;
      var upperBound = data[r][dataColumn - 1];

      data[r][groupColumn - 1] = groupID;
    }
  }

  dataRange.setValues(data);
}

Первое, что делает код, - открывает лист с SpreadsheetApp.getActive(), Spreadsheet.getActiveSheet(). После этого код ищет диапазон данных с Sheet.getRange() (обратите внимание, как он использует Sheet.getLastRow() и Sheet.getLastColumn(), чтобы найти размер диапазона) и сортирует его с помощью Range.sort(), используя столбец оценки в качестве ссылки. Позже он считывает диапазон с помощью Range.getValues(). Кроме того, я инициализировал некоторые переменные, такие как столбцы идентификатора и группы, желаемый процент группировки (5%) в этом случае и исходный идентификатор группы (0).

После всей этой инициализации код будет повторяться каждую строку и проверьте, находится ли значение данных (Score в примере) на расстоянии ± 5% от верхней границы группы (самое высокое значение в группе). Если значение находится в диапазоне ± 5%, идентификатор группы будет удален. Если он не входит в диапазон, будет сгенерирован новый идентификатор группы, а верхняя граница будет взята из этой записи. Процесс будет продолжаться до тех пор, пока все записи не получат идентификатор группы, после чего данные будут внесены в таблицу с Range.setValues(). Окончательный результат выглядит так:

Final example

А теперь, почему я использовал результаты тестов вместо роста? Что ж, посмотрите, что происходит с примером высот с использованием предыдущего кода:

Heights example

Генерируются только две группы (0 и 1) потому что расстояние между реалистичными c высотами меньше ± 5%. Я надеюсь, что мой ответ поможет вам, но не стесняйтесь задавать мне дополнительные сомнения.


ОБНОВЛЕНИЕ

На основе обновления вопроса в вашем комментарии я изменил сценарий. Если я правильно понимаю, вам нужна средняя точка в каждой группе и рассчитываются границы группы на основе этой средней точки плюс / минус 5%. Если мое предположение верно, вы можете использовать следующий код:

function calculateGroupBounds(groupingPercentage, groupUpperBound) {
  var groupBounds = {};
  groupBounds['groupUpperBound'] = groupUpperBound;
  groupBounds['groupMidpoint'] = 100 * groupUpperBound / (100 +
    groupingPercentage);
  groupBounds['groupLowerBound'] = (100 - groupingPercentage) * groupBounds[
    'groupMidpoint'] / 100;

  return groupBounds;
}

function so62060595B() {
  // Sheet reading
  var dataColumn = 2; // Column B
  var groupColumn = 3; // Column C
  var dataSheet = SpreadsheetApp.getActive().getActiveSheet();
  var dataRange = dataSheet.getRange(2, 1, dataSheet.getLastRow() - 1, dataSheet
    .getLastColumn()).sort({
    column: dataColumn,
    ascending: false
  });
  var data = dataRange.getValues();

  // Group initialization
  var groupingPercentage = 5; // 5%
  var groupID = 0;
  var groupUpperBound = data[0][dataColumn - 1];
  var groupBounds = calculateGroupBounds(groupingPercentage, groupUpperBound)
  var groupMidpoint = groupBounds['groupMidpoint'];
  var groupLowerBound = groupBounds['groupLowerBound'];

  for (var r = 0; r < data.length; r++) {
    if (data[r][dataColumn - 1] <= groupUpperBound && data[r][dataColumn - 1] >=
      groupLowerBound) {
      // Include in the same group
      data[r][groupColumn - 1] = groupID;
    } else {
      // Create a new group
      var groupID = groupID + 1;
      var upperBound = data[r][dataColumn - 1];
      var groupBounds = calculateGroupBounds(groupingPercentage,
        upperBound)
      var groupMidpoint = groupBounds['groupMidpoint'];
      var groupLowerBound = groupBounds['groupLowerBound'];

      data[r][groupColumn - 1] = groupID;
    }
  }

  dataRange.setValues(data);
}

Этот новый код использует те же методы скрипта приложений, что и предыдущий, и включает новую функцию (calculateGroupBounds()) для вычисления верхнего и нижние границы и середина. В итерации данных код проверяет, находится ли значение между верхней и нижней границей, и если это так, группа iD будет удалена. Если этого не произойдет, будет создана новая группа. Это результат с теми же данными примера, что и предыдущий код:

Scores example using Code II

И это результат с таблицей высот:

Heights example using Code II

Эти результаты такие же, как и в предыдущем коде, хотя мы используем другой подход во втором коде. Это связано с тем, что в первом коде я использовал математические свойства для разделения данных на группы ± 5% без вычисления средней точки. Пожалуйста, задайте мне любые сомнения, если вам все еще нужна помощь.

0 голосов
/ 28 мая 2020

Думаю, вы можете использовать пакет. Для Excel openpyxl является таким важным пакетом в python. Вы можете выполнять сортировку, ввод данных, создание диаграмм в Excel с помощью этого пакета в python. Сначала go по этой ссылке.

https://pypi.org/ найдите openpyxl и установите этот пакет.

https://openpyxl.readthedocs.io/en/stable/tutorial.html#create -a-workbook эта ссылка предназначена для руководства по использованию openpyxl.

...