Вычислить среднее из каждых x строк в таблице и создать новую таблицу

У меня длинная таблица данных (~ 200 строк по 50 столбцов), и мне нужно создать код, который может вычислять средние значения каждых двух строк и для каждого столбца в таблице, причем конечный результат является новой таблицей среднего значения. Это, очевидно, сумасшествие в Excel! Я использую python3, и мне известны некоторые подобные вопросы: здесь , здесь и здесь . Но ни один из них не помогает, поскольку мне нужен элегантный код для работы с несколькими столбцами и создается организованная таблица данных. Кстати, мой оригинальный datatable был импортирован с помощью pandas и определен как dataframe, но не смог найти простой способ сделать это в пандах. Помощь очень ценится.

Пример таблицы (короткая версия):

abcd 2 50 25 26 4 11 38 44 6 33 16 25 8 37 27 25 10 28 48 32 12 47 35 45 14 8 16 7 16 12 16 30 18 22 39 29 20 9 15 47 

Ожидаемая средняя таблица:

 abcd 3 30.5 31.5 35 7 35 21.5 25 11 37.5 41.5 38.5 15 10 16 18.5 19 15.5 27 38 

  • Какие кодировки файлов поддерживаются для исходных файлов Python 3?
  • StringIO в python3
  • даты соответствия с использованием регулярных выражений python
  • Неожиданное поведение itertools.groupby
  • Запоминание, когда аргументы могут быть очень большими
  • Биномиальный коэффициент Python
  • Как получить имя файла и lineno атрибута SyntaxError
  • Получить содержимое веб-страницы с помощью Python?
  • 3 Solutions collect form web for “Вычислить среднее из каждых x строк в таблице и создать новую таблицу”

    Вы можете создать искусственную группу, используя df.index//2 (или как указано @DSM, используя np.arange(len(df))//2 – чтобы он работал для всех индексов), а затем используйте groupby:

     df.groupby(np.arange(len(df))//2).mean() Out[13]: abcd 0 3.0 30.5 31.5 35.0 1 7.0 35.0 21.5 25.0 2 11.0 37.5 41.5 38.5 3 15.0 10.0 16.0 18.5 4 19.0 15.5 27.0 38.0 

    NumPythonic способ состоял бы в том, чтобы извлечь элементы в виде массива NumPy с df.values , а затем преобразовать в 3D массив с 2 элементами вдоль axis=1 и 4 вдоль axis=2 и выполнить среднее сокращение вдоль axis=1 и, наконец, преобразовать обратно в блок данных, например,

     pd.DataFrame(df.values.reshape(-1,2,df.shape[1]).mean(1)) 

    Как оказалось, вы можете ввести очень эффективный инструмент NumPy: np.einsum сделать это average-reduction как комбинацию sum-reduction и scaling-down , например,

     pd.DataFrame(np.einsum('ijk->ik',df.values.reshape(-1,2,df.shape[1]))/2.0) 

    Обратите внимание, что предлагаемые подходы предполагают, что количество строк делится на 2 .

    Также, как noted by @DSM , для сохранения имен столбцов вам необходимо добавить columns=df.columns при преобразовании в Dataframe, то есть –

     pd.DataFrame(...,columns=df.columns) 

    Пример прогона –

     >>> df 0 1 2 3 0 2 50 25 26 1 4 11 38 44 2 6 33 16 25 3 8 37 27 25 4 10 28 48 32 5 12 47 35 45 6 14 8 16 7 7 16 12 16 30 8 18 22 39 29 9 20 9 15 47 >>> pd.DataFrame(df.values.reshape(-1,2,df.shape[1]).mean(1)) 0 1 2 3 0 3 30.5 31.5 35.0 1 7 35.0 21.5 25.0 2 11 37.5 41.5 38.5 3 15 10.0 16.0 18.5 4 19 15.5 27.0 38.0 >>> pd.DataFrame(np.einsum('ijk->ik',df.values.reshape(-1,2,df.shape[1]))/2.0) 0 1 2 3 0 3 30.5 31.5 35.0 1 7 35.0 21.5 25.0 2 11 37.5 41.5 38.5 3 15 10.0 16.0 18.5 4 19 15.5 27.0 38.0 

    Тесты времени выполнения –

    В этом разделе давайте проверим все три подхода, перечисленные до сих пор, чтобы решить проблему производительности, в том числе @ayhan's solution with groupby .

     In [24]: A = np.random.randint(0,9,(200,50)) In [25]: df = pd.DataFrame(A) In [26]: %timeit df.groupby(df.index//2).mean() # @ayhan's solution 1000 loops, best of 3: 1.61 ms per loop In [27]: %timeit pd.DataFrame(df.values.reshape(-1,2,df.shape[1]).mean(1)) 1000 loops, best of 3: 317 µs per loop In [28]: %timeit pd.DataFrame(np.einsum('ijk->ik',df.values.reshape(-1,2,df.shape[1]))/2.0) 1000 loops, best of 3: 266 µs per loop 
     df.set_index(np.arange(len(df)) // 2).mean(level=0) 
    Python - лучший язык программирования в мире.