Pandas为每行分配其区间的均值

1 投票
2 回答
506 浏览
提问于 2025-04-18 06:02

我有一个这样的数据表(p1.head(7)):

     ColA
0    6.286333
1    3.317000
2    13.24889
3    26.20667
4    26.25556
5    60.59000
6    79.59000
7    1.361111

我可以通过以下方式获取区间范围:

pandas.qcut(p1.ColA, 4)

有没有办法创建一个新列,让每个值对应于这个区间的平均值?也就是说,对于每个区间 (a,b],我想要 (a+b)/2。

2 个回答

1

我写了一个函数,来使用 @exp1orer 的逻辑:

def midway_quantiles(feature_series,q=4):
    import pandas as pd
    pctiles = pd.qcut(feature_series,q,retbins=True)
    pctile_object = pctiles[0]
    df1= pd.DataFrame({"feature":feature_series,"q_bound": pctile_object})
    pctile_boundaries = pctiles[1]
    import numpy as np
    bin_halfway = pctile_boundaries[:-1] + (np.diff(pctile_boundaries)/2)
    df2 = pd.DataFrame({"q_bound": pctile_object.cat.categories, 
                            "midpoint": bin_halfway})
    df3=pd.merge(df1,df2,on="q_bound",how="left")
    return df3["midpoint"]
1

这里的关键是 qcut 里的 retbins 选项。

import pandas
df = pandas.DataFrame(np.random.random(100)*100, columns=['val1'])

pctiles = pandas.qcut(df['val1'],4,retbins=True)
pctile_object = pctiles[0]
pctile_boundaries = pctiles[1]

在这里,pctile_object 就是如果你没有设置 retbins=True 时,qcut 会返回的结果,而 pctile_boundaries 是一个包含区间边界的 numpy 数组。

import numpy
bin_halfway = pctile_boundaries[:-1] + (numpy.diff(pctile_boundaries)/2)

这给我们提供了每个区间的中间点。

接下来,我们创建一个只包含区间名称(作为字符串)和中间点的数据框。

df2 = pandas.DataFrame({'quartile boundaries': pctile_object.levels, 
                        'midway point': bin_halfway})

最后,把这些区间的中间点合并回原来的数据框中。

df['quartile boundaries'] = pctile_object
pandas.merge(df,df2,on='quartile boundaries')

然后,如果你想的话,可以删除 quartile boundaries

撰写回答