我在 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]
我想將一年中每個月的溫度從最低到最高排序。然后計算每個月和每年的累積分布函式(cdf)。
我設法用過濾器做到了這一點,只查看一個特定的月份和特定的年份。現在我正在努力在所有月份和年份中應用此代碼。我的代碼看起來像這樣:
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
最后得到:
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
我懷疑我將不得不回圈這個。但我不知道如何。
uj5u.com熱心網友回復:
作為單個代碼塊
沒有回圈,沒有 lambda 函式。非常快(從 1990 年到 2022-01-01 的 11,688 行大約為 90 毫秒)。
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)
)
解釋(一點一滴)
如果您首先將列組合day, month, year成一個date并將其作為索引,這會更容易。
僅使用您提供的四行作為示例資料:
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
現在,您可以非常輕松地按月分組。例如,計算每個月的平均溫度:
>>> 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
現在,對于您問題的第二部分:如何對月份內的溫度重新排序,并計算它的 CDF。我們先生成隨機資料進行測驗:
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]
對每個月內的溫度進行排序:
by_month = pd.Grouper(freq='M')
df = df.assign(
temp_sorted=df.groupby(by_month)['Temperature'].transform(sorted)
)
注意:雖然使用上面的值,看起來溫度已經在全球范圍內重新排序,但事實并非如此。它們僅在每個月內重新訂購。例如:
>>> 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
最后,計算每個月內的 CDF:
df = df.assign(
CDF_temp=df.groupby(by_month)['temp_sorted'].agg('rank', pct=True)
)
我們得到:
>>> 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/403842.html
標籤:
上一篇:pandasdf中的條件計數
