[英]Run function for each month of the year within a dataframe
I have a DataFrame in pandas, which has daily temperature values for each month of the years 2010 and 2011:我在 pandas 中有一个 DataFrame,它有 2010 年和 2011 年每个月的每日温度值:
> day month year Temperature
> 1 1 2010 269.798567
> 1 1 2011 274.085177
> ....
> 31 12 2010 273.610214
> 31 12 2011 274.855967
> [730 rows x 4 columns]
I want to sort the temperature from least to greatest for each month of the year.我想将一年中每个月的温度从最低到最高排序。 And calculate afterwards the cumulative distribution function (cdf) of each month and year.然后计算每个月和年的累积分布 function (cdf)。
I managed to do this with a filter, looking at only one specific month and one specific year .我设法通过过滤器做到这一点,只查看一个特定的月份和一个特定的年份。 Now I'm struggling to apply this code for all months and years .现在我正在努力将这个代码应用到所有的月份和年份。 My code looks like that:我的代码如下所示:
month = 1
year = 2010
filt = (df['month'] == month) & (df['year'] == year)
dfMonth = df.loc[filt]
#Sort temperature from least to greatest
SortDF = dfMonth.sort_values(variable,ascending=True)
# calculate cdf
NumberOfDays = len(SortDF)
EmptyList = list(range(1, NumberOfDays+1))
CDF = [((element -0.5)/NumberOfDays)for element in EmptyList if element < NumberOfDays]
CDF.append(1)
# Add CDF values into Dataframe as new column
SortDF['CDF' + '_' + Temperature ] = CDF
And get finally:最后得到:
day month year Temperature CDF_Temperature
25 1 2010 259.990152 0.016129
24 1 2010 260.644554 0.048387
....
28 1 2010 272.642832 0.951613
10 1 2010 273.004253 1.000000
I suspect that I will have to loop this.我怀疑我将不得不循环这个。 But I have no idea how.但我不知道怎么做。
df = df.assign(
date=pd.to_datetime(df[['day', 'month', 'year']])
).set_index('date')[['Temperature']]
by_month = pd.Grouper(freq='M')
df = df.assign(
temp_sorted=df.groupby(by_month)['Temperature'].transform(sorted)
)
df = df.assign(
CDF_temp=df.groupby(by_month)['temp_sorted'].agg('rank', pct=True)
)
This is easier if you first combine your columns day, month, year
into a single date
column.如果您首先将列day, month, year
合并到一个date
列中,这会更容易。
Using just the four rows you provided as sample data:仅使用您提供的四行作为示例数据:
df = pd.DataFrame({
'day': [1, 1, 31, 31],
'month': [1, 1, 12, 12],
'year': [2010, 2011, 2010, 2011],
'Temperature': [269.798567, 274.085177, 273.610214, 274.855967],
})
df = df.assign(
date=pd.to_datetime(df[['day', 'month', 'year']])
).set_index('date')[['Temperature']]
>>> df
Temperature
date
2010-01-01 269.798567
2011-01-01 274.085177
2010-12-31 273.610214
2011-12-31 274.855967
Now, you can group by month very easily.现在,您可以非常轻松地按月分组。 For example, computing the mean temperature for each month:例如,计算每个月的平均温度:
>>> df.groupby(pd.Grouper(freq='M')).mean()
Temperature
date
2010-01-31 269.798567
2010-02-28 NaN
...
2010-11-30 NaN
2010-12-31 273.610214
2011-01-31 274.085177
2011-02-28 NaN
...
2011-11-30 NaN
2011-12-31 274.855967
Now, for the second part of your question: how to reorder the temperatures within the month, and compute a CDF of it.现在,对于您问题的第二部分:如何重新排序当月的温度,并计算它的 CDF。 Let's first generate random data for testing:让我们首先生成随机数据进行测试:
np.random.seed(0) # reproducible values
ix = pd.date_range('2010', '2012', freq='D', closed='left')
df = pd.DataFrame(
np.random.normal(270, size=len(ix)),
columns=['Temperature'], index=ix)
>>> df
Temperature
2010-01-01 271.764052
2010-01-02 270.400157
2010-01-03 270.978738
2010-01-04 272.240893
2010-01-05 271.867558
... ...
2011-12-27 269.112819
2011-12-28 269.067211
2011-12-29 271.243319
2011-12-30 270.812674
2011-12-31 270.587259
[730 rows x 1 columns]
Sort the temperatures within each month:对每个月内的温度进行排序:
by_month = pd.Grouper(freq='M')
df = df.assign(
temp_sorted=df.groupby(by_month)['Temperature'].transform(sorted)
)
Note: while, with the values above, it looks like the temperatures have been reordered globally, this is not the case.注意:虽然使用上面的值,看起来温度已经在全球范围内重新排序,但事实并非如此。 They have been reordered only within each month.它们仅在每个月内重新订购。 For example:例如:
>>> df['2010-01-30':'2010-02-02']
Temperature temp_sorted
2010-01-30 271.469359 272.240893
2010-01-31 270.154947 272.269755
2010-02-01 270.378163 268.019204
2010-02-02 269.112214 268.293730
Finally, compute the CDF within each month:最后,计算每个月内的 CDF:
df = df.assign(
CDF_temp=df.groupby(by_month)['temp_sorted'].agg('rank', pct=True)
)
And we get:我们得到:
>>> df
Temperature temp_sorted CDF_temp
2010-01-01 271.764052 267.447010 0.032258
2010-01-02 270.400157 268.545634 0.064516
2010-01-03 270.978738 269.022722 0.096774
2010-01-04 272.240893 269.145904 0.129032
2010-01-05 271.867558 269.257835 0.161290
... ... ... ...
2011-12-27 269.112819 271.094638 0.870968
2011-12-28 269.067211 271.243319 0.903226
2011-12-29 271.243319 271.265078 0.935484
2011-12-30 270.812674 271.327783 0.967742
2011-12-31 270.587259 272.132153 1.000000
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.