Мне нужно знать количество осадков между двумя последовательными измерениями влажности почвы (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 - -
Я новичок, пробовал разные подходы, но не получилось. Спасибо за любую помощь, которую вы можете мне оказать!
потому что вам нужно накапливать значения в разном количестве строк, поэтому, возможно, вам придется использовать обычный for
-цикл для запуска сложного кода, который запоминает предыдущие данные и запускает вычисления только тогда, когда есть значение в SM
Что там с датами? Они вышли из строя и дублируются. Я написал некоторый код, который получает желаемый результат, но полностью игнорирует даты, поэтому IDK, если мой код неверен или данные/описание примера неверны.
Вы можете идентифицировать числовые строки в 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)
что ты пробовал? Покажите это в вопросе, а не в комментариях.