2015-01-17 23 views
9

Tôi không chắc chắn làm thế nào để thực hiện điều này mà không cần gán chuỗi (có thể sẽ không hoạt động anyways vì tôi muốn thiết lập một bản sao).Pandas: Cách thích hợp để đặt giá trị dựa trên điều kiện cho tập hợp con của multiindex dataframe

Tôi không thể lấy một tập hợp con của một khung dữ liệu gấu trúc multiindex, kiểm tra các giá trị nhỏ hơn 0 và đặt chúng về 0.

Ví dụ:

df = pd.DataFrame({('A','a'): [-1,-1,0,10,12], 
        ('A','b'): [0,1,2,3,-1], 
        ('B','a'): [-20,-10,0,10,20], 
        ('B','b'): [-200,-100,0,100,200]}) 

df[df['A']<0] = 0.0 

cho

In [37]: 

df 

Out[37]: 
    A B 
    a b a b 
0 -1 0 -20 -200 
1 -1 1 -10 -100 
2 0 2 0 0 
3 10 3 10 100 
4 12 -1 20 200 

nào cho thấy rằng nó đã không thể thiết lập dựa trên điều kiện. Ngoài ra nếu tôi đã làm một nhiệm vụ xích:

df.loc[:,'A'][df['A']<0] = 0.0 

này cho kết quả tương tự (và thiết lập với cảnh báo bản sao)

tôi có thể lặp qua mỗi cột dựa trên điều kiện là cấp độ đầu tiên là một trong những mà tôi muốn:

for one,two in df.columns.values: 
    if one == 'A': 
     df.loc[df[(one,two)]<0, (one,two)] = 0.0 

mang đến cho kết quả mong muốn:

In [64]: 

df 

Out[64]: 
    A B 
    a b a b 
0 0 0 -20 -200 
1 0 1 -10 -100 
2 0 2 0 0 
3 10 3 10 100 
4 12 0 20 200 

Nhưng bằng cách nào đó tôi cảm thấy có một cách tốt hơn để làm điều này hơn là lặp qua các cột. Cách tốt nhất để làm điều này trong gấu trúc là gì?

Trả lời

9

Đây là một ứng dụng của (và là một trong những động lực chính cho việc sử dụng máy thái MultiIndex), xem tài liệu here

In [20]: df = pd.DataFrame({('A','a'): [-1,-1,0,10,12], 
        ('A','b'): [0,1,2,3,-1], 
        ('B','a'): [-20,-10,0,10,20], 
        ('B','b'): [-200,-100,0,100,200]}) 

In [21]: df 
Out[21]: 
    A  B  
    a b a b 
0 -1 0 -20 -200 
1 -1 1 -10 -100 
2 0 2 0 0 
3 10 3 10 100 
4 12 -1 20 200 

In [22]: idx = pd.IndexSlice 

In [23]: mask = df.loc[:,idx['A',:]]<0 

In [24]: mask 
Out[24]: 
     A  
     a  b 
0 True False 
1 True False 
2 False False 
3 False False 
4 False True 

In [25]: df[mask] = 0 

In [26]: df 
Out[26]: 
    A  B  
    a b a b 
0 0 0 -20 -200 
1 0 1 -10 -100 
2 0 2 0 0 
3 10 3 10 100 
4 12 0 20 200 

Vì bạn đang làm việc với cấp 1 của chỉ số cột, sau đây sẽ làm việc như tốt. Ví dụ trên là tổng quát hơn, nói rằng bạn muốn làm điều này cho 'a'.

In [30]: df[df[['A']]<0] = 0 

In [31]: df 
Out[31]: 
    A  B  
    a b a b 
0 0 0 -20 -200 
1 0 1 -10 -100 
2 0 2 0 0 
3 10 3 10 100 
4 12 0 20 200 
+1

Xin lỗi, cảm ơn! Sử dụng slicer để tạo ra một mặt nạ trông thực sự hữu ích (có thể phải sử dụng điều này trong nhiều mã của tôi). Ví dụ thứ hai giải quyết vấn đề cụ thể của tôi. Tôi đã không nhận thức được sự khác biệt giữa 'df ['A']' và 'df [['A']]' – pbreach

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