python - 可以对数据框中的每一列应用百分位数切割吗?

时间:2016-02-16 19:22:07

标签: python pandas vectorization quantile

是否可以使用循环对数据帧的所有列进行百分位切割?这就是我现在这样做的方式:

df = pd.DataFrame(np.random.randn(10,5))
df_q = pd.DataFrame()

for i in list(range(len(df.columns))):
    df_q[i] = pd.qcut(df[i], 5, labels=list(range(5)))

我希望有一个灵巧的熊猫解决方案,以避免使用循环。

谢谢!

1 个答案:

答案 0 :(得分:3)

pd.qcut接受1D数组或Series作为其参数。要将pd.qcut应用于每个列,需要多次调用pd.qcut。所以不管你怎么打扮,都会有一个循环 - 无论是显性的还是隐含的。

例如,您可以使用apply为每列调用pd.qcut

In [46]: df.apply(lambda x: pd.qcut(x, 5, labels=list(range(5))), axis=0)
Out[46]: 
   0  1  2  3  4
0  4  0  3  0  3
1  0  0  2  3  0
2  3  4  1  2  3
3  4  1  1  1  4
4  3  2  2  4  1
5  2  4  3  0  1
6  2  3  0  4  4
7  1  3  4  2  2
8  0  1  4  3  0
9  1  2  0  1  2

但在幕后,df.apply正在使用for-loop,因此它与您的for-loop没有什么不同:

df_q = pd.DataFrame()
for col in df:
    df_q[col] = pd.qcut(df[col], 5, labels=list(range(5)))
In [47]: %timeit df.apply(lambda x: pd.qcut(x, 5, labels=list(range(5))), axis=0)
100 loops, best of 3: 2.9 ms per loop

In [48]: %%timeit
    df_q = pd.DataFrame()
    for col in df:
        df_q[col] = pd.qcut(df[col], 5, labels=list(range(5)))
100 loops, best of 3: 2.95 ms per loop

请注意

for i in list(range(len(df.columns))):

仅在df的列恰好是从0开始的连续整数时才起作用。 它使用起来更健壮

for col in df:

迭代DataFrame的列。