Панды нормализуют столбец, проиндексированный по datetimeindex по сумме даты по группам - PullRequest
0 голосов
/ 17 декабря 2018

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

Я могу легко сгруппировать по дате и вычислить делитель (сумма значений каждогостолбец для каждой даты), но я не совсем уверен, что лучший способ разделить исходный кадр данных на результирующую сумму df.

Пример кадра данных с datetimeindex и результирующий df из суммы

Я попытался сделать что-то вроде

df / df.groupby(df.index.to_period('D')).sum()

, но все идет не так, как я ожидал.

Вместо этого я получаю df с NaN везде и добавляется датав качестве новых индексов.

т.е. Результаты вышеприведенного деления

Игрушечный отдых:

df = pd.DataFrame([[1,2],[3,4],[5,6],[7,8]],columns=['a','b'], 
              index=pd.to_datetime(['2017-01-01 14:30:00','2017-01-01 14:31:00', 
                                    '2017-01-02 14:30:00', '2017-01-02 14:31:00']))
df / df.groupby(df.index.to_period('D')).sum()

приводит к

                     a  b
2017-01-01 14:30:00 NaN NaN
2017-01-01 14:31:00 NaN NaN
2017-01-02 14:30:00 NaN NaN
2017-01-02 14:31:00 NaN NaN
2017-01-01  NaN NaN
2017-01-02  NaN NaN

1 Ответ

0 голосов
/ 17 декабря 2018

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

образец df

df1 = pd.DataFrame(np.random.randn(5,5), columns=list('ABCDE'),
                  index=pd.date_range('2017-01-03', '2017-01-07'))

df2 = pd.DataFrame(np.random.randn(5,5), columns=list('ABCDE'),
                  index=pd.date_range('2017-01-03', '2017-01-07'))

df = pd.concat([df1,df2])

               A            B          C            D           E
2017-01-03  1.393874    1.933301    0.215026    -0.412957   -0.293925
2017-01-04  0.825777    0.315449    2.317292    -0.347617   -2.427019
2017-01-05  -0.372916   -0.931185   0.049707    0.635828    -0.774566
2017-01-06  1.564714    -1.582461   1.455403    0.521305    -2.175344
2017-01-07  1.255747    1.967338    -0.766391   -0.021921   0.672704
2017-01-03  0.620301    -1.521681   -0.352800   -1.394239   -1.206983
2017-01-04  -0.041829   -0.870871   -0.402440   0.268725    1.499321
2017-01-05  -1.098647   1.690136    1.004087    0.304037    1.235310
2017-01-06  0.305645    -0.327096   0.280591    -0.476904   1.652096
2017-01-07  1.251927    0.469697    0.047694    1.838995    -0.258889

тогда, что вы естьв настоящее время выполняется:

df / df.groupby(df.index).sum()

                A           B           C          D            E
2017-01-03  0.692032    4.696817    -1.560723   0.228507    0.195831
2017-01-03  0.307968    -3.696817   2.560723    0.771493    0.804169
2017-01-04  1.053357    -0.567944   1.210167    4.406211    2.616174
2017-01-04  -0.053357   1.567944    -0.210167   -3.406211   -1.616174
2017-01-05  0.253415    -1.226937   0.047170    0.676510    -1.681122
2017-01-05  0.746585    2.226937    0.952830    0.323490    2.681122
2017-01-06  0.836585    0.828706    0.838369    11.740853   4.157386
2017-01-06  0.163415    0.171294    0.161631    -10.740853  -3.157386
2017-01-07  0.500762    0.807267    1.066362    -0.012064   1.625615
2017-01-07  0.499238    0.192733    -0.066362   1.012064    -0.625615

Посмотрите на первую строку col A

1.393874 / (1.393874 + 0.620301) = 0.6920322216292031, поэтому ваш пример df / df.groupby(df.index).sum() работает как положено.

Также будьте осторожны, если ваши данные содержат NaN, потому что np.nan / a number = nan

обновление за комментарий:

df = pd.DataFrame([[1,2],[3,4],[5,6],[7,8]],columns=['a','b'], 
              index=pd.to_datetime(['2017-01-01 14:30:00','2017-01-01 14:31:00', 
                                    '2017-01-02 14:30:00', '2017-01-02 14:31:00']))


# create multiindex with level 1 being just dates
df.set_index(df.index.floor('D'), inplace=True, append=True)

# divide df by the group sum matching the index values of level 1
df.div(df.groupby(level=1).sum(), level=1).reset_index(level=1, drop=True)

                          a         b
2017-01-01 14:30:00   0.250000  0.333333
2017-01-01 14:31:00   0.750000  0.666667
2017-01-02 14:30:00   0.416667  0.428571
2017-01-02 14:31:00   0.583333  0.571429
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...