分位数计算原理参见《python–pandas 分位数》
下面直接使用pandas的quantile方法
import pandas as pd
df = pd.DataFrame({'a': [3, 3, 3, 3, 3, 3, 3]})
sum(df["a"] == 3)
Out[1]: 7
df['a'].quantile(0.9) # 90%分位数
Out[2]: 3.0
df['a'].quantile(0.8) # 80%分位数
Out[3]: 3.0
但是无论是pandas的quantile还是numpy的quantile,尤其是在原数据位数很长时,会有如下这样一个精度问题,这就造成有时候我想找>=分位数的一些数据却不能如愿。

由于只会在最后几位会有些毛病,我的处理是:如果前6位的数据相同,则判定为相等。(这个取几位数看你自己需求哈,我觉得6位数够了)。即:
# 获得a列取值>=90%分位数的数据
df[df["a"].round(6) >= df["a"].quantile(0.9).round(6)]
def cls(dat, by_metric="a"):
"""
在by_metric列算分位数、然后按照分位数分组
:param dat: dataframe
:param by_metric:
:return: High组,Low组的dataframe
"""
# 计算大于分位数为0.9的预测值索引,记为High组
high_idx = dat[dat[by_metric].round(6) >= dat[by_metric].quantile(0.9).round(6)].index
dat_high = dat.loc[high_idx]
# 计算小于分位数为0.1的预测值索引,记为Low组
low_idx = dat[dat[by_metric].round(6) <= dat[by_metric].quantile(0.1).round(6)].index
dat_low = dat.loc[low_idx]
return dat_high , dat_low
基于Bin_ws_hub、ws_up/ws_down、TI进行数据筛选,
import pandas as pd
import os
from datetime import datetime
def main():
workdir = r'F:\02-data\142-output\142-lidar_data_csv'
outfile = r'F:\02-data\data_filter{}.xlsx'.format(
datetime.now().strftime('%m%d_%H%M'))
# 加载数据
wind_data = pd.read_excel(os.path.join(workdir, 'data_cluster.xlsx'), sheet_name=0)
# 初始化最终结果的DataFrame
final_data = pd.DataFrame()
# 对每个'Bin_ws_hub'进行操作
for bin_ws_hub in wind_data['Bin_ws_hub'].unique():
hub_data = wind_data[wind_data['Bin_ws_hub'] == bin_ws_hub]
# 计算'ws_up/ws_down'的百分位数
ws_percentiles = hub_data['ws_up/ws_down'].quantile([0.05, 0.50, 0.95])
for ws_perc in ws_percentiles:
# 找到最接近ws_up/ws_down百分位数的一行
ws_closest = hub_data.iloc[(hub_data['ws_up/ws_down'] - ws_perc).abs().argsort()[:10]] # 可以调整这个值,以获取间隔更大的TI
# 计算'TI'的百分位数
ti_percentiles = ws_closest['TI'].quantile([0.05, 0.50, 0.95])
for ti_perc in ti_percentiles:
# 找到最接近TI百分位数的一行
ti_closest = ws_closest.iloc[(ws_closest['TI'] - ti_perc).abs().argsort()[:1]]
# 添加到最终结果
final_data = pd.concat([final_data, ti_closest])
# 去除重复行(如果有的话)
final_data = final_data.drop_duplicates()
# 重置索引
final_data = final_data.reset_index(drop=True)
final_data.to_excel(outfile, index=False)