2013-01-12 31 views
10

Tôi có một khung dữ liệu với các cột số. Đối với mỗi cột, tôi muốn tính toán thông tin định lượng và gán mỗi hàng cho một trong số chúng. Tôi đã cố gắng sử dụng qcut() method để trả lại danh sách thùng nhưng thay vào đó sẽ tính riêng từng thùng. Những gì tôi nghĩ có thể tồn tại nhưng tôi không thể tìm thấy nó sẽ là một phương pháp như df.to_quintile(num of quantiles). Đây là những gì tôi đã đưa ra nhưng tôi tự hỏi nếu có một cách succint/gấu trúc hơn để làm điều này.Chuyển dữ liệu vào thùng định lượng

import pandas as pd 

#create a dataframe 
df = pd.DataFrame(randn(10, 4), columns=['A', 'B', 'C', 'D']) 

def quintile(df, column): 
    """ 
    calculate quintiles and assign each sample/column to a quintile 
    """ 
    #calculate the quintiles using pandas .quantile() here 
    quintiles = [df[column].quantile(value) for value in [0.0,0.2,0.4,0.6,0.8]] 
    quintiles.reverse() #reversing makes the next loop simpler 

    #function to check membership in quintile to be used with pandas apply 
    def check_quintile(x, quintiles=quintiles): 
     for num,level in enumerate(quintiles): 
      #print number, level, level[1] 
      if x >= level: 
       print x, num 
       return num+1 

    df[column] = df[column].apply(check_quintile) 

quintile(df,'A') 

cảm ơn, zach cp

EDIT: Sau khi nhìn thấy DSMs trả lời các chức năng có thể được viết đơn giản hơn nhiều (dưới đây). Người đàn ông, đó là ngọt ngào.

def quantile(column, quantile=5): 
    q = qcut(column, quantile) 
    return len(q.levels)- q.labels 
df.apply(quantile) 
#or 
df['A'].apply(quantile) 

Trả lời

13

Tôi nghĩ rằng bằng cách sử dụng labels được lưu trữ bên trong đối tượng Categorical trả về bởi qcut có thể làm điều này rất nhiều đơn giản hơn. Ví dụ:

>>> import pandas as pd 
>>> import numpy as np 
>>> np.random.seed(1001) 
>>> df = pd.DataFrame(np.random.randn(10, 2), columns=['A', 'B']) 
>>> df 
      A   B 
0 -1.086446 -0.896065 
1 -0.306299 -1.339934 
2 -1.206586 -0.641727 
3 1.307946 1.845460 
4 0.829115 -0.023299 
5 -0.208564 -0.916620 
6 -1.074743 -0.086143 
7 1.175839 -1.635092 
8 1.228194 1.076386 
9 0.394773 -0.387701 
>>> q = pd.qcut(df["A"], 5) 
>>> q 
Categorical: A 
array([[-1.207, -1.0771], (-1.0771, -0.248], [-1.207, -1.0771], 
     (1.186, 1.308], (0.569, 1.186], (-0.248, 0.569], (-1.0771, -0.248], 
     (0.569, 1.186], (1.186, 1.308], (-0.248, 0.569]], dtype=object) 
Levels (5): Index([[-1.207, -1.0771], (-1.0771, -0.248], 
        (-0.248, 0.569], (0.569, 1.186], (1.186, 1.308]], dtype=object) 
>>> q.labels 
array([0, 1, 0, 4, 3, 2, 1, 3, 4, 2]) 

hoặc để phù hợp với mã của bạn:

>>> len(q.levels) - q.labels 
array([5, 4, 5, 1, 2, 3, 4, 2, 1, 3]) 
>>> quintile(df, "A") 
>>> np.array(df["A"]) 
array([5, 4, 5, 1, 2, 3, 4, 2, 1, 3]) 
+0

nhờ DSM. Tôi không nhận ra rằng đầu ra qcut() có nhãn. Đó là những gì tôi cần! – zach

+0

Cảm ơn @ DSM, tôi không biết rằng qcut/cut có thuộc tính label (không hiển thị trong tự động hoàn thành IPython). Cho đến nay tôi nghĩ rằng tôi đã phải gọi 'nhãn = False' để gọi hàm để có được các nhãn là tốt. Nhưng nó đẹp hơn thế này. – tim

Các vấn đề liên quan