Как я могу рассчитать совокупную сумму значений в меняющемся временном окне с помощью Pandas?

Мне нужно знать количество осадков между двумя последовательными измерениями влажности почвы (SM) и разницей влажности почвы (дельтаSM).

df= pd.read_excel('Dataset.xlsx')

df['Datetime']=pd.to_datetime(df['Date'])
df=df.set_index('Datetime')

Мои данные выглядят так:

Date         SM   Rain
01/01/2016   0.23   0
02/01/2016     -    0
03/01/2016     -    10
04/01/2016   0.15   0
05/01/2016   0.30   0.1
06/01/2016     -    0
07/01/2016     -    5.2
08/01/2016     -    12.3
05/01/2016   0.40   0.5
06/01/2016     -    0
07/01/2016   0.25   0
08/01/2016     -    0
.
.
.

Я хотел бы получить:

Date         SM   Rain  deltaSM  Rsum
01/01/2016   0.23   0      -      0
02/01/2016     -    0      -      -
03/01/2016     -    10     -      -
04/01/2016   0.15   0    -0.08    10.0
05/01/2016   0.30   0.1   0.15    0.1
06/01/2016     -    0      -      -
07/01/2016     -    5.2    -      -
08/01/2016     -    12.3   -      -
05/01/2016   0.40   0.5   0.10    18.0
06/01/2016     -    0      -      -
07/01/2016   0.25   0    -0.15    0
08/01/2016     -    0      -      -

Я новичок, пробовал разные подходы, но не получилось. Спасибо за любую помощь, которую вы можете мне оказать!

что ты пробовал? Покажите это в вопросе, а не в комментариях.

furas 24.05.2024 22:32

потому что вам нужно накапливать значения в разном количестве строк, поэтому, возможно, вам придется использовать обычный for-цикл для запуска сложного кода, который запоминает предыдущие данные и запускает вычисления только тогда, когда есть значение в SM

furas 24.05.2024 22:35

Что там с датами? Они вышли из строя и дублируются. Я написал некоторый код, который получает желаемый результат, но полностью игнорирует даты, поэтому IDK, если мой код неверен или данные/описание примера неверны.

wjandrea 25.05.2024 00:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете идентифицировать числовые строки в SM, а затем использовать это для вычисления маски для diff и группера для groupby.sum / groupby.transform:

s = pd.to_numeric(df['SM'], errors='coerce')
m = s.notna()

df['deltaSM'] = s[m].diff()

df.loc[m, 'Rsum'] = df['Rain'].groupby(m[::-1].cumsum()).transform('sum')

# or
# df.loc[m, 'Rsum'] = (df['Rain']
#                      .groupby(m[::-1].cumsum(), sort=False)
#                      .sum().values[:-1]
#                      )

Выход:

          Date    SM  Rain  deltaSM  Rsum
0   01/01/2016  0.23   0.0      NaN   0.0
1   02/01/2016     -   0.0      NaN   NaN
2   03/01/2016     -  10.0      NaN   NaN
3   04/01/2016  0.15   0.0    -0.08  10.0
4   05/01/2016  0.30   0.1     0.15   0.1
5   06/01/2016     -   0.0      NaN   NaN
6   07/01/2016     -   5.2      NaN   NaN
7   08/01/2016     -  12.3      NaN   NaN
8   05/01/2016  0.40   0.5     0.10  18.0
9   06/01/2016     -   0.0      NaN   NaN
10  07/01/2016  0.25   0.0    -0.15   0.0
11  08/01/2016     -   0.0      NaN   NaN

Решение @mozway великолепно. Здесь я нашел более длинное решение, просто хотел поделиться своим длинным путем :))

import pandas as pd

# Sample data
data = {
    'Date': ['01/01/2016', '02/01/2016', '03/01/2016', '04/01/2016', '05/01/2016', 
             '06/01/2016', '07/01/2016', '08/01/2016', '05/01/2016', '06/01/2016', 
             '07/01/2016', '08/01/2016'],
    'SM': [0.23, None, None, 0.15, 0.30, None, None, None, 0.40, None, 0.25, None],
    'Rain': [0, 0, 10, 0, 0.1, 0, 5.2, 12.3, 0.5, 0, 0, 0]
}

# Create DataFrame
df = pd.DataFrame(data)

# Initialize columns for deltaSM and Rsum
df['deltaSM'] = '-'
df['Rsum'] = '-'

# Variables to track the previous SM value and cumulative Rain sum
prev_sm = None
cum_rain = 0

# Iterate through the DataFrame to calculate deltaSM and Rsum
for idx, row in df.iterrows():
    cum_rain += row['Rain']
    print('index: ', idx, '-', row['SM'], row['Rain'])
    if pd.notna(row['SM']):
        if prev_sm is not None:
            df.at[idx, 'deltaSM'] = row['SM'] - prev_sm
            df.at[idx, 'Rsum'] = cum_rain
            cum_rain = 0  # Reset cumulative Rain sum after calculation
        prev_sm = row['SM']
    

# Convert 'deltaSM' and 'Rsum' columns to proper types
df['deltaSM'] = pd.to_numeric(df['deltaSM'], errors='coerce')
df['Rsum'] = pd.to_numeric(df['Rsum'], errors='coerce')

# Convert 'Date' to datetime and set as index
df['Date'] = pd.to_datetime(df['Date'], format='%d/%m/%Y')
df = df.set_index('Date')

print(df)

Другие вопросы по теме