Как рассчитать совокупную недельную сумму значений, если у меня есть ежедневные значения, используя панд? - PullRequest
2 голосов
/ 01 ноября 2019

Я начинающий пользователь Pandas. У меня есть датафрейм, который выглядит следующим образом:

days rainfall
1    3.51
2    1.32
3    0
4    0
5    0
6    0
7    0
8    0
9    0.03
10   0
11   0
12   0.17
13   0.23
14   0.02
15   0
16   0
17   0
18   0.03
19   0.02
20   0
21   0

Я хотел бы добавить столбец (назовем его «кумулятивный»), который показывает совокупные значения осадков за каждую неделю. Другими словами, я хочу вычислить совокупные значения для первых семи дней (1-7), затем второго набора из семи дней (8-14) и так далее.

Конечный продукт будет выглядеть так:

days rainfall cumulative
1    3.51     4.83
2    1.32     0.45
3    0        0.05
4    0
5    0
6    0
7    0
8    0
9    0.03
10   0
11   0
12   0.17
13   0.23
14   0.02
15   0
16   0
17   0
18   0.03
19   0.02
20   0
21   0

До сих пор я пытался дозвониться до rolling с sum, но я не получаю то, что хочу.

df['cumulative']=df['rainfall'].rolling(min_periods=7, window=7).sum()

Благодарен за любые советы или рекомендации!

Ответы [ 3 ]

1 голос
/ 01 ноября 2019

Если я вас правильно понимаю, вы хотите GroupBy.transform:

# create groups of each 7 days with floordivision
grps = df['days'].sub(1).floordiv(7)

# get the cumulative sum per group
df['cumsum'] = df.groupby(grps)['rainfall'].transform('sum')

    days  rainfall  cumsum
0      1      3.51    4.83
1      2      1.32    4.83
2      3      0.00    4.83
3      4      0.00    4.83
4      5      0.00    4.83
5      6      0.00    4.83
6      7      0.00    4.83
7      8      0.00    0.45
8      9      0.03    0.45
9     10      0.00    0.45
10    11      0.00    0.45
11    12      0.17    0.45
12    13      0.23    0.45
13    14      0.02    0.45
14    15      0.00    0.05
15    16      0.00    0.05
16    17      0.00    0.05
17    18      0.03    0.05
18    19      0.02    0.05
19    20      0.00    0.05
20    21      0.00    0.05
1 голос
/ 01 ноября 2019

Вы можете сделать это так:

import pandas as pd

df = pd.DataFrame([
    [ 1, 3.51],
    [ 2, 1.32],
    [ 3, 0],
    [ 4, 0],
    [ 5, 0],
    [ 6, 0],
    [ 7, 0],
    [ 8, 0],
    [9, 0.03],
    [10, 0],
    [11, 0],
    [12, 0.17],
    [13, 0.23],
    [14, 0.02],
    [15, 0],
    [16, 0],
    [17, 0],
    [18, 0.03],
    [19, 0.02],
    [20, 0],
    [21, 0]], columns=['days', 'rainfall'])
result = df['rainfall'].groupby((df['days'] - 1) // 7).sum().reset_index(drop=True)
print(result)
# In [418]: %paste -q
# 0    4.83
# 1    0.45
# 2    0.05
# Name: rainfall, dtype: float64
0 голосов
/ 01 ноября 2019

РЕДАКТИРОВАТЬ: еще один метод, который работает без индексов DateTime, это pd.cut ().

    df.groupby(pd.cut(df.days, bins=3, 
        precision=0))["rainfall"].sum()
    days
    (1.0, 8.0]      4.83
    (8.0, 14.0]     0.45
    (14.0, 21.0]    0.05

Метод вырезания позволяет вам указать диапазон частот для значений бина.

    pd.cut(df.days, bins=3)

- это способ сказать «возьми серию df [« дни »] и раздели ее на три части». Если вы запустите этот код один, вы увидите:

    0       (1.0, 8.0]
    1       (1.0, 8.0]
    2       (1.0, 8.0]
    .
    .
    .
    19    (14.0, 21.0]
    20    (14.0, 21.0]

Он помечает каждую строку в вашем DataFrame тем, к какому бину он принадлежит. Затем вы можете использовать его в качестве аргумента в выражении groupby, как и любой другойатрибут столбца и применить статистическую функцию.

Помещение ["rainfall"] вне оператора groupby является способом сказать: "Это столбец, который я хочу получить суммой" (т. е. не суммируйтедней). Вы можете поочередно написать это сначала, если это более интуитивно понятно. (Это здорово, а также расстраивает, что у панд есть более чем один и только один правильный способ сделать что-то.)

df["rainfall"].groupby(...)

ОРИГИНАЛЬНЫЙ ОТВЕТ:

Для совокупной статистики вы можетеиспользуйте pd.resample (). Это метод индекса DateTime (мне пришлось немного привести его здесь, но обычно у вас будет больше информации о погодных метках).

    df.resample("W").sum()["rainfall"]

- это код для сокращения дней до недель и агрегирования значений.

В этом случае я создал DataFrame из словаря и преобразовал индекс в формат DateTime, чтобы использовать метод повторной выборки:

    df = pd.DataFrame( 
        data={
            "days": (list(range(1,22))), 
            "rainfall": [3.51,
                1.32, 0, 0, 0, 0, 0, 0, 0.03, 
                0, 0, 0.17, 0.23, 0.02, 0, 0,  
                0, 0.03, 0.02, 0, 0]}, 
             index=pd.to_datetime(list(range(1,22)), format="%d",
             errors="coerce"))

, который возвращает вас:

    1900-01-07    4.83
    1900-01-14    0.45
    1900-01-21    0.05
    Freq: W-SUN, Name: rainfall, dtype: float64

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

...