Reputation: 482
I have a precipitation data-series in a Pandas DataFrame with as index the dates between 2009-2018 (3652). I'm trying to find a way to decrease or increase proportional the cumulative precipitation relative to the mean by a given percentage (decrease for values < mean, increase for values > mean).
What I managed to do
Making a list with only non-zero values, sort it and increase or decrease the values proportional to the place of the mean value. Like this:
The blue line represents the original values. The orange line a 200% (for clear example) increase and decrease (there are now negative values but with a percentage of 20% that won't happen). The mean is 4.65 and in this case on place 1261.
The Problem Now I wan't to do this for a Dataframe like below, but keep all the precipitation values in place.
[3652 rows x 1 columns]
Precipitation
2009-01-01 0.000000
2009-01-02 0.600000
2009-01-03 0.000000
2009-01-04 0.900000
2009-01-05 2.000000
2009-01-06 0.000000
...
Question Is someone familiar how to increase or decrease values proportional to the mean. So that the highest and lowest values actual increase and decrease 20% but all the values in between proportional.
Upvotes: 1
Views: 274
Reputation: 5740
Assumption is that you y data i always growing when its going into bigger x. Otherwise you need to sort data first.
First you need to create column with percentage proportion according to df shape. Then calculate new value.
Here You go:
=^..^=
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# create test data
x = np.arange(1,20,1)
y = x**0.1
df = pd.DataFrame(y, columns=['data'])
# find value for proportion shape
def proportion_value(df):
for i in np.arange(0.1, 100, 0.1):
if len(df)-1 < i < len(df):
return i
percentage = 20
# load proportion
df['proportion'] = np.arange(-percentage, percentage, (percentage*2)/proportion_value(df))/100
# calculate new data
df['new_data'] = df['data'] + (df['data']*df['proportion'])
# plot data
df[['data', 'new_data']].plot()
plt.show()
Output:
Upvotes: 1