将DF中的值替换为相对于其他值的四分位数

时间:2014-11-07 01:19:20

标签: python pandas

我有一个巨大的CSV文件,其中包含一系列项目ID的指标,我正在尝试相互比较,我希望找到每个指标中每个项目的四分位数,并用其四分位数替换每个实际数字在列内。下面显示了一些虚拟数据的示例。如果指标具有NaN值,我想完全忽略它们。因此对于Metric 2,四分位数将基于具有10个值而不是12个值的列。

ID     Metric 1     Metric 2     Metric 3
-----------------------------------------
1      10           4.8          155          
2      11           5.6          301
3      7            7.9          223
4      14           NaN          88
5      4            NaN          109
6      18           6.6          213
7      13           3.9          456
8      5            8.1          403
9      10           9.2          353
10     11           4.1          312
11     9            5.3          286
12     6            3.3          215


ID     Metric 1     Metric 2     Metric 3
-----------------------------------------
1      2            2            1          
2      3            3            3
3      2            4            2
4      4            NaN          1
5      1            NaN          1
6      4            3            2
7      4            1            4
8      1            4            4
9      2            4            4
10     3            2            3
11     2            2            3
12     1            1            2

我知道在熊猫中有更好的方法,只需循环遍历每个单元格,但我不太清楚如何处理它。

1 个答案:

答案 0 :(得分:1)

你正在寻找带有标签集的Pandas中的qcut方法。这是一个例子:

创建示例数据:

df1 = pd.DataFrame({'M1': randint(size=12, low=100, high = 500)})
df1['ID'] = df1.index
print df1.head()


    M1  ID
0  281   0
1  455   1
2  401   2
3  313   3
4  432   4

只要没有分组,只需使用qcut()

创建一个新变量
df1['M1Q'] = pd.qcut(df1.M1, 4, labels=[1,2,3,4])
print df1

     M1  ID M1Q
0   281   0   3
1   455   1   4
2   401   2   4
3   313   3   3
4   432   4   4
5   208   5   3
6   207   6   2
7   205   7   2
8   130   8   1
9   126   9   1
10  167  10   2
11  163  11   1

根据帮助文件,qcut()使用nulls执行您想要的操作。但我们不妨向自己证明这一点。让我们吹出一些数据然后再次运行:

df1.M1.iloc[8:] = NaN
df1['M1Q'] = pd.qcut(df1.M1, 4, labels=[1,2,3,4])
print df1

     M1  ID M1Q
0   356   0   3
1   466   1   4
2   420   2   3
3   429   3   4
4   165   4   1
5   140   5   1
6   231   6   2
7   230   7   2
8   NaN   8 NaN
9   NaN   9 NaN
10  NaN  10 NaN
11  NaN  11 NaN

我认为这看起来就像你追求的那样。祝你好运!