2013-07-16 42 views
41

Tôi tự hỏi nếu có một cách đơn giản hơn, hiệu quả về bộ nhớ để chọn một tập con các hàng và cột từ một DataFrame gấu trúc.Làm thế nào để chuyển đổi một tập hợp con DataFrame của các cột AND hàng thành một mảng numpy?

Ví dụ, cho dataframe này:

 
df = DataFrame(np.random.rand(4,5), columns = list('abcde')) 
print df 

      a   b   c   d   e 
0 0.945686 0.000710 0.909158 0.892892 0.326670 
1 0.919359 0.667057 0.462478 0.008204 0.473096 
2 0.976163 0.621712 0.208423 0.980471 0.048334 
3 0.459039 0.788318 0.309892 0.100539 0.753992 

tôi muốn chỉ những hàng mà giá trị cho cột 'c' là lớn hơn 0,5, nhưng tôi chỉ cần cột 'b' và 'e' cho những hàng đó.

Đây là phương pháp mà tôi đã đưa ra - có lẽ có một cách "tốt hơn" gấu trúc?

 
locs = [df.columns.get_loc(_) for _ in ['a', 'd']] 
print df[df.c > 0.5][locs] 

      a   d 
0 0.945686 0.892892 

mục tiêu cuối cùng của tôi là để chuyển đổi kết quả vào một mảng NumPy để vượt qua thành một thuật toán hồi quy sklearn, vì vậy tôi sẽ sử dụng đoạn mã trên như thế này:

 
training_set = array(df[df.c > 0.5][locs]) 

... và rằng Peeves tôi kể từ khi tôi kết thúc với một bản sao mảng lớn trong bộ nhớ. Có lẽ có một cách tốt hơn cho điều đó?

Trả lời

8

.loc chấp nhận bộ chọn hàng và cột cùng một lúc (như .ix/.iloc FYI) Việc này cũng được thực hiện trong một lần chuyển.

In [1]: df = DataFrame(np.random.rand(4,5), columns = list('abcde')) 

In [2]: df 
Out[2]: 
      a   b   c   d   e 
0 0.669701 0.780497 0.955690 0.451573 0.232194 
1 0.952762 0.585579 0.890801 0.643251 0.556220 
2 0.900713 0.790938 0.952628 0.505775 0.582365 
3 0.994205 0.330560 0.286694 0.125061 0.575153 

In [5]: df.loc[df['c']>0.5,['a','d']] 
Out[5]: 
      a   d 
0 0.669701 0.451573 
1 0.952762 0.643251 
2 0.900713 0.505775 

Và nếu bạn muốn giá trị (mặc dù điều này nên chuyển trực tiếp tới sklearn); khung hỗ trợ giao diện mảng

In [6]: df.loc[df['c']>0.5,['a','d']].values 
Out[6]: 
array([[ 0.66970138, 0.45157274], 
     [ 0.95276167, 0.64325143], 
     [ 0.90071271, 0.50577509]]) 
+0

Thanh lịch nhất. Sự khác biệt giữa .ix và .loc là gì? –

+0

loc sẽ không cố gắng sử dụng một số (ví dụ 1) làm đối số vị trí ở tất cả (và sẽ tăng lên); xem tài liệu gấu trúc chính/chọn dữ liệu – Jeff

70

Sử dụng giá trị của nó trực tiếp:

In [79]: df[df.c > 0.5][['b', 'e']].values 
Out[79]: 
array([[ 0.98836259, 0.82403141], 
     [ 0.337358 , 0.02054435], 
     [ 0.29271728, 0.37813099], 
     [ 0.70033513, 0.69919695]]) 
+0

Tôi không biết về thuộc tính .values. Rất đẹp! Ngoài ra, hơi sạch hơn kể từ khi bạn loại bỏ các dấu ngoặc đơn và dấu ngoặc đơn và thay vì sử dụng df.c trực tiếp. –

+1

đẹp nhưng nó khác với 'as_matrix' như thế nào? – dashesy

+5

Chỉ cần cập nhật, vì tôi đã tự hỏi về sự khác biệt giữa as_matrix và .values ​​(vì tôi chỉ sử dụng .values). Nó chỉ ra rằng as_matrix chỉ được cung cấp cho khả năng tương thích ngược, và nó được khuyến khích sử dụng .values ​​thay thế. Xem http://pandas.pydata.org/pandas-docs/version/0.17.1/generated/pandas.DataFrame.as_matrix.html – DkM

16

Có lẽ một cái gì đó như thế này cho vấn đề đầu tiên, bạn chỉ có thể truy cập vào các cột bằng tên của họ:

>>> df = pd.DataFrame(np.random.rand(4,5), columns = list('abcde')) 
>>> df[df['c']>.5][['b','e']] 
      b   e 
1 0.071146 0.132145 
2 0.495152 0.420219 

Đối với vấn đề thứ hai:

>>> df[df['c']>.5][['b','e']].values 
array([[ 0.07114556, 0.13214495], 
     [ 0.49515157, 0.42021946]]) 
Các vấn đề liên quan