Проблема с функцией pandas.DataFrame.cumsum - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть следующий фрейм данных в python:

month = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,2,3,4]
active = [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1]
data1 = [1709.1,3869.7,4230.4,4656.9,48566.0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93738.2,189293.2,194412.6,206585.8]
df = pd.DataFrame({
                    'month' : month,
                    'active' : active,
                    'd1' : data1,
                    'calculate' : 0,
                });

, и я хочу вычислить столбец «вычисления» следующим образом:

    month  active        d1  calculate
0       1       1    1709.1     569.70
1       2       1    3869.7    1859.60
2       3       1    4230.4    3269.73
3       4       1    4656.9    4822.03
4       5       0   48566.0       0.00
5       6       0       0.0       0.00
6       7       0       0.0       0.00
7       8       0       0.0       0.00
8       9       0       0.0       0.00
9      10       0       0.0       0.00
10     11       0       0.0       0.00
11     12       0       0.0       0.00
12     13       0       0.0       0.00
13     14       0       0.0       0.00
14     15       0       0.0       0.00
15     16       0       0.0       0.00
16     17       0       0.0       0.00
17     18       0       0.0       0.00
18     19       0       0.0       0.00
19     20       0       0.0       0.00
20      1       1   93738.2   31246.07
21      2       1  189293.2   94343.80
22      3       1  194412.6  159148.00
23      4       1  206585.8  228009.93

Я делаю это вследующим образом:

df['calculate'] = np.where(
                        df.month > 1,
                        np.where(
                                    df.active,
                                    (df.d1/3).cumsum(),
                                    0,
                        ),
                        (df['d1']/3)
                    )

но результат не тот, который ожидался:

    month  active        d1      calculate
0       1       1    1709.1     569.700000
1       2       1    3869.7    1859.600000
2       3       1    4230.4    3269.733333
3       4       1    4656.9    4822.033333
4       5       0   48566.0       0.000000
5       6       0       0.0       0.000000
6       7       0       0.0       0.000000
7       8       0       0.0       0.000000
8       9       0       0.0       0.000000
9      10       0       0.0       0.000000
10     11       0       0.0       0.000000
11     12       0       0.0       0.000000
12     13       0       0.0       0.000000
13     14       0       0.0       0.000000
14     15       0       0.0       0.000000
15     16       0       0.0       0.000000
16     17       0       0.0       0.000000
17     18       0       0.0       0.000000
18     19       0       0.0       0.000000
19     20       0       0.0       0.00
20      1       1   93738.2   31246.07
21      2       1  189293.2  115354.50
22      3       1  194412.6  180158.70
23      4       1  206585.8  249020.63

Я не знаю, ясно ли я в своем запросе, я благодарю, кто может помочь мне.

1 Ответ

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

Новый ответ

Вы чрезмерно усложнили свою проблему с вашими условиями, ваша проблема может быть уменьшена до:

df.groupby(df.active.ne(df.active.shift()).cumsum()).d1.cumsum().div(3) * df.active

0        569.700000
1       1859.600000
2       3269.733333
3       4822.033333
4          0.000000
5          0.000000
6          0.000000
7          0.000000
8          0.000000
9          0.000000
10         0.000000
11         0.000000
12         0.000000
13         0.000000
14         0.000000
15         0.000000
16         0.000000
17         0.000000
18         0.000000
19         0.000000
20     31246.066667
21     94343.800000
22    159148.000000
23    228009.933333
dtype: float64

Старый ответ (я думаю, что все еще полезно включить, чтобы объяснить логику того, что пыталось сделать)

Вытребуется только совокупная сумма последовательных областей, равная 1 с, однако, когда вы доберетесь до конца вашего DataFrame, вы продолжите с накопленной суммой остальной части DataFrame.Одним из решений является вычисление cumsum на группу последовательных 1 с, а затем использование этого результата в вашей окончательной проверке.


Мне также нравится избегать цепочки вызовов на np.where, когда np.select многолегче читать.

s = df.groupby(df.active.ne(df.active.shift()).cumsum()).d1.cumsum()

c1 = df.month.gt(1) & df.active
c2 = df.month.gt(1) & ~df.active

df.assign(calculate=np.select([c1, c2], [s.div(3), 0], df.d1.div(3)))

    month  active        d1      calculate
0       1       1    1709.1     569.700000
1       2       1    3869.7    1859.600000
2       3       1    4230.4    3269.733333
3       4       1    4656.9    4822.033333
4       5       0   48566.0       0.000000
5       6       0       0.0       0.000000
6       7       0       0.0       0.000000
7       8       0       0.0       0.000000
8       9       0       0.0       0.000000
9      10       0       0.0       0.000000
10     11       0       0.0       0.000000
11     12       0       0.0       0.000000
12     13       0       0.0       0.000000
13     14       0       0.0       0.000000
14     15       0       0.0       0.000000
15     16       0       0.0       0.000000
16     17       0       0.0       0.000000
17     18       0       0.0       0.000000
18     19       0       0.0       0.000000
19     20       0       0.0       0.000000
20      1       1   93738.2   31246.066667
21      2       1  189293.2   94343.800000
22      3       1  194412.6  159148.000000
23      4       1  206585.8  228009.933333
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...