微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Python 中沿第 3 维取百分位数

如何解决在 Python 中沿第 3 维取百分位数

我一直在为这个问题苦苦挣扎。我有一个 55115 x 34 的矩阵,其中第一个维度上的每个数字是一天,151 年,总共 55115 个点。

我试图获取一个维度中值的每月百分位数,因此我首先添加一个日期列,随后将其分组为几个月,尽管我无法找出获取百分位数(第 95 个)的最佳方法天数和第三维(这里是 34)。所以在对月份进行分组之后,矩阵应该是 151 x 12 x 34,我想沿第三维取第 95 个百分位数,所以我的最终矩阵理论上应该是 151 x 12。以下是我到目前为止将日期添加到数组中的内容

dates = pd.date_range(start='1950-01-01',end='2100-12-31',freq='D') #create daily date range from 1950 to 2100

leap = [] #empty array
for each in dates:
    if each.month==2 and each.day ==29: #find each leap day (feb 29)
        leap.append(each)

dates = dates.drop(leap) #get rid of leap days
dates = pd.to_datetime(dates) #convert to datetime format 
data = {'wind': winddata,'time': dates} #create table with both dates and data
df = pd.DataFrame(data) #create dataframe
df.set_index('time') #index time
df.groupby(df['time'].dt.strftime('%b'))['wind'].sort_values()

这就是我必须取的百分位数:

months = df.groupby(pd.Grouper(key='time',freq = "M")) #group each month
monthly_percentile = months.aggregate(lambda x: np.percentile(x,q = 95)) #percentile across each month 

虽然,这似乎不起作用。我对这样做的其他方法持开放态度,我只是希望 a) 将 55115 x 34 数据集重新排列为几个月,使其为 151(年)x 365(天)x 34(集合),然后百分位数是跨月份和第三维的,所以我最终得到 151 x 12。如果我指定得不够好,我很乐意澄清任何事情。任何详细的回复都会非常有帮助。在此先感谢您!

解决方法

如果我的问题是正确的,我能想到的最直接的解决方案是添加列 yearmonth,然后对它们进行分组并计算所需的百分位数:

import pandas as pd
import numpy as np

dates = pd.date_range(start='1950-01-01',end='2100-12-31',freq='D')
dates_months = [date.month for date in dates]
dates_years = [date.year for date in dates]
values = np.random.rand(34,len(dates))
df = pd.DataFrame()

df['date'] = dates
df['year'] = dates_years
df['month'] = dates_months
for i in range(34):
    df[f'values_{i}'] = values[i]

df = df.melt(id_vars=['date','year','month'],value_vars=[f'values_{i}' for i in range(34)])
sub = df.groupby(['year','month']).value.apply(lambda x: np.quantile(x,.95)).reset_index()

最后,如果你真的需要一个 151 x 12 数组而不是长度为 1812 (=151*12) 的年-月-百分位表,你可以使用这样的东西:

crosstab = pd.crosstab(index=sub['year'],columns=sub['month'],values=sub['values'],aggfunc=lambda x: x)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。