Pandas bin Dataframe - PullRequest
       2

Pandas bin Dataframe

0 голосов
/ 19 сентября 2018

У меня есть фрейм данных со столбцом глубины с сеткой 0,1 м.

import pandas as pd


df1 = pd.DataFrame({'depth': [1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1 ],
            '350': [7.898167, 6.912074, 6.049002, 5.000357, 4.072320, 3.070662, 2.560458, 2.218879, 1.892131, 1.588389, 1.573693],
            '351': [8.094912, 7.090584, 6.221289, 5.154516, 4.211746, 3.217615, 2.670147, 2.305846, 1.952723, 1.641423, 1.622722],
            '352': [8.291657, 7.269095, 6.393576, 5.308674, 4.351173, 3.364569, 2.779837, 2.392813, 2.013316, 1.694456, 1.671752],
            '353': [8.421007, 7.374317, 6.496641, 5.403691, 4.439815, 3.412494, 2.840625, 2.443868, 2.069017, 1.748445, 1.718081 ],
            '354': [8.535562, 7.463452, 6.584512, 5.485725, 4.517310, 3.438680, 2.890678, 2.487039, 2.123644, 1.802643, 1.763818 ],
            '355': [8.650118, 7.552586, 6.672383, 4.517310, 4.594806, 3.464867, 2.940732, 2.530211, 2.178271, 1.856841, 1.809555 ]},
            index=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
             )

У меня такой вопрос: как я могу связать данные для получения нового кадра данных на частоте глубины 0,5 м?

Или, скорее, как мне усреднить значения столбца из df1 (которые имеют данные на каждые 0,1 м) для бункеров dz = 0,5 м?

Смысл в том, чтобы получить ту же структуру df, те же столбцы (350-355), но строки должны быть усреднены / разбиты по столбцам для определенного интервала dz (количество строк), скажем, 0,5 м

Таким образом, мой новый информационный кадр будет иметь только две строки в этом случае со значениями глубины 1,35 и 1,85 м, сохраняя каждый столбец как в df1.Первый будет иметь усредненные значения для интервала 1,1-1,6 м, второй от 1,6-2,1 м.

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

Что-то вроде этого:

In [33]: g = df1.groupby(by=lambda i: 1.35 if i < 1.7 else 1.85)

In [34]: g.mean()
Out[34]:
           350       351       352       353       354       355  depth
1.35  7.898167  8.094912  8.291657  8.421007  8.535562  8.650118   1.10
1.85  3.493796  3.608861  3.723926  3.794699  3.855750  3.811756   1.65

Обратите внимание, что вам все равно нужно обновить столбец 'глубина'.Кроме того, функцию by для groupby можно сделать «умнее» - вычислить глубину для автоматического использования на основе кадра данных ...

0 голосов
/ 19 сентября 2018

Используйте комбинацию df.groupby и pd.cut

import pandas as pd
import numpy as np

# Specifiy your desired dz step size
step = 0.5
dz = np.arange(1,3,step)

# rebin dataframe
df2 = df1.groupby(pd.cut(df1.depth, dz, labels=False), as_index=False).mean()

# refill 'depth' column
df2.depth = dz[:-1]

, чтобы получить

depth   350     351     352     353     354     355
0   1.0     5.986384    6.154609    6.322835    6.427094    6.517312    6.397441
1   1.5     2.266104    2.357551    2.448998    2.502890    2.548537    2.594184
2   2.0     1.573693    1.622722    1.671752    1.718081    1.763818    1.809555

, где в каждой строке есть среднее значение столбцов 35x в 1 < x <= 1.5, 1.5 < x <= 2 и т. Д. *

Вы можете легко изменить перебазирование, выбрав нужное значение для переменной step.

0 голосов
/ 19 сентября 2018

Вам просто нужно определить группировщика, а затем выполнить стандартную групповую работу.Удвоение, а затем использование целочисленного усечения - это один из способов.Обратите внимание, что я также вычел небольшое количество (sub(0.001)) только для того, чтобы это соответствовало краям ячейки для ответа @gehbiszumeis - но это всего лишь произвольное решение о кромке ячейки, которое можно было бы опустить.

df1['grp'] = df1.depth.sub(0.001).mul(2).astype(int)
df1.groupby('grp').mean()

Результаты:

    depth       350       351       352       353       354       355
grp                                                                   
2      1.3  5.986384  6.154609  6.322835  6.427094  6.517312  6.397441
3      1.8  2.266104  2.357551  2.448998  2.502890  2.548537  2.594184
4      2.1  1.573693  1.622722  1.671752  1.718081  1.763818  1.809555

В качестве альтернативы вы можете использовать pd.bin подход, такой как @gehbiszumeis, который немного более элегантен.Вот вариант этого подхода, который приводит к интервальному индексу:

df1['depth_range'] = pd.cut( df1.depth, pd.interval_range(start=1.0,end=2.5,freq=0.5) )
df1.groupby('depth_range').mean()

             depth       350       351       352       353       354       355
depth_range                                                                   
(1.0, 1.5]     1.3  5.986384  6.154609  6.322835  6.427094  6.517312  6.397441
(1.5, 2.0]     1.8  2.266104  2.357551  2.448998  2.502890  2.548537  2.594184
(2.0, 2.5]     2.1  1.573693  1.622722  1.671752  1.718081  1.763818  1.809555
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...