pandas使用分位数+控制变量法进行多条件数据筛选

文章目录

  • 1、给个例子
  • 2、精度问题
  • 3、最后给可用函数
  • 4、筛选函数

引自:https://blog.csdn.net/weixin_43469047/article/details/124783768
作者:小白tree

分位数计算原理参见《python–pandas 分位数》
下面直接使用pandasquantile方法

1、给个例子

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

2、精度问题

但是无论是pandasquantile还是numpyquantile,尤其是在原数据位数很长时,会有如下这样一个精度问题,这就造成有时候我想找>=分位数的一些数据却不能如愿。
pandas使用分位数+控制变量法进行多条件数据筛选_第1张图片
由于只会在最后几位会有些毛病,我的处理是:如果前6位的数据相同,则判定为相等。(这个取几位数看你自己需求哈,我觉得6位数够了)。即:

# 获得a列取值>=90%分位数的数据
df[df["a"].round(6) >= df["a"].quantile(0.9).round(6)]

3、最后给可用函数

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

4、筛选函数

基于Bin_ws_hub、ws_up/ws_down、TI进行数据筛选,

  • 对Bin_ws_hub去重,逐个遍历
  • 对每一个Bin_ws_hub,去选取其对应数据中ws_up/ws_down的[0.05, 0.50, 0.95]三个分位数,筛选接近每个分位数附近数据各10个(可按需按数据量进行调节)
  • 对每个Bin_ws_hub的每个ws_up/ws_down,从其(例如0.5分位数)对应的10个TI中,选择TI的3个分位数,得到33Bin_ws_hub的总的数据量。
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)

你可能感兴趣的:(利用Python进行数据分析,pandas)