Как сгруппировать столбец каждый раз, когда его сумма достигает указанной суммы? - PullRequest
1 голос
/ 28 апреля 2020

У меня есть фрейм данных df вот так

     x
0    8.86
1    1.12
2    0.56
3    5.99
4    3.08
5    4.15

Мне нужно выполнить какую-то операцию groupby на x, чтобы агрегировать x каждый раз, когда его сумма достигает 10. Если индекс df был объектом datetime, я мог бы использовать pd.Grouper, как показано ниже

grouped = df.groupby(pd.Grouper(freq="min")
grouped["x"].sum()

, который будет группировать по индексу datetime, а затем суммировать x каждую минуту. В моем случае у меня нет цели datetime, поэтому df.groupby(pd.Grouper(freq=10)) дает ValueError: Invalid frequency: 10.

Желаемый выходной кадр данных после применения операций groupby() и sum() будет выглядеть следующим образом

     y
0    10.54
1    13.22

, потому что элементы 0-2 из df составляют до 10,54, а элементы 3-5 - до 13,22

Как можно сгруппировать x по его сумме, каждый раз, когда сумма достигает 10?

Ответы [ 2 ]

2 голосов
/ 28 апреля 2020

Вот один подход:

# cumulative sum and modulo 10
s = df.x.cumsum().mod(10)
# if value lower than 10, we've reached the value
m = s.diff().lt(0)
# groupby de cumsum
df.x.groupby(m.cumsum().shift(fill_value=0)).sum()

x
0    10.54
1    13.22
Name: x, dtype: float64
0 голосов
/ 28 апреля 2020

Вы можете сделать это с for-l oop и скользящими суммами.

data_slices = [] # Store each sample
rollingSum = 0
last_t = 0
for t in range(len(df)):
    rollingSum += df['x'][t] # Add the t index value to sum
    if rollingSum >= 10:
        data_slice = df['x'][last_t:t] # Slice of x column that sums over 10
        data_slices.append(data_slice)
        rollingSum = 0 # Reset the sum
        last_t = t # Set this as the start index of next slice

grouped_data = pd.concat(data_slices, axis=0)
...