2016-03-29 17 views
12

Dường như pd.rolling_mean đang trở nên bị phản đối cho ndarrays,pd.rolling_mean trở thành bị phản đối - giải pháp thay thế cho ndarrays

pd.rolling_mean(x, window=2, center=False) 

FutureWarning: pd.rolling_mean bị phản đối cho ndarrays và sẽ được loại bỏ trong một phiên bản tương lai

nhưng dường như đây là cách nhanh nhất để thực hiện việc này, theo số this SO answer.

Có cách nào mới để thực hiện việc này trực tiếp với SciPy hoặc NumPy nhanh như pd.rolling_mean không?

+0

Tôi vẫn không thấy câu trả lời cho câu hỏi "Chức năng rolling_mean thay thế cho ndarrays là gì?" Điều này nên được bao gồm trong scipy hoặc numpy mà không cần phải dựa vào một chức năng Pandas dự định để sử dụng trên Dataframes – Mike

Trả lời

2

Hình như các phương pháp mới là thông qua phương pháp trên lớp DataFrame.rolling (tôi đoán bạn đang có nghĩa là để nghĩ về nó giống như một groupby): http://pandas.pydata.org/pandas-docs/version/0.18.0/whatsnew.html

ví dụ

x.rolling(window=2).mean() 
+0

Vâng, tôi nhận ra điều đó. Đã bao gồm điều này trong câu hỏi. Trong mọi trường hợp, nó chỉ ra nhanh như vậy mặc dù nó đòi hỏi phải chuyển 'x' thành' pd.Series' trước tiên (xem câu trả lời của tôi với chi tiết). –

-1

Nếu kích thước của bạn là đồng nhất, bạn có thể cố gắng thực hiện một hình thức n-chiều của Summed Area Table sử dụng cho hình ảnh hai chiều:

Một bảng khu vực tóm tắt là một cấu trúc dữ liệu và thuật toán cho một cách nhanh chóng và tạo hiệu quả tổng các giá trị trong một tập hợp con hình chữ nhật của một lưới.

Sau đó, theo thứ tự này, bạn có thể:

  1. Tạo bảng tổng diện tích ("không thể thiếu") của mảng của bạn;
  2. Lặp lại để có được tổng (khá rẻ) của hạt nhân n chiều tại một vị trí nhất định;
  3. Chia nhỏ theo kích thước của khối lượng n-chiều của hạt nhân.

Rất tiếc, tôi không thể biết điều này có hiệu quả hay không, nhưng theo lý do đã cho, nó phải như vậy.

7

EDIT - Thật không may, có vẻ như con đường mới không phải là gần như nhanh:

Phiên bản mới của gấu trúc:

In [1]: x = np.random.uniform(size=100) 

In [2]: %timeit pd.rolling_mean(x, window=2) 
1000 loops, best of 3: 240 µs per loop 

In [3]: %timeit pd.Series(x).rolling(window=2).mean() 
1000 loops, best of 3: 226 µs per loop 

In [4]: pd.__version__ 
Out[4]: '0.18.0' 

Phiên bản cũ:

In [1]: x = np.random.uniform(size=100) 

In [2]: %timeit pd.rolling_mean(x,window=2) 
100000 loops, best of 3: 12.4 µs per loop 

In [3]: pd.__version__ 
Out[3]: u'0.17.1' 
+0

điểm tốt và có vẻ như bạn đã đúng. Xem chỉnh sửa của tôi.Tôi sẽ mở câu hỏi một lần nữa để xem liệu có ai khác có giải pháp ở đây để giữ lại tốc độ cũ hơn không. –

+0

dang yeah! – maxymoo

+0

Xem ở đây: điều này * nên * chỉ thêm một chút chi phí cuộc gọi chức năng, nhưng điều này có một bản sao không cần thiết của các khối nội bộ, sửa chữa dễ dàng: https://github.com/pydata/pandas/issues/12732 – Jeff

0

Tôi đề nghị scipy.ndimage.filters.uniform_filter1d như trong số answer của tôi cho câu hỏi được liên kết. Đó cũng là cách nhanh hơn cho các mảng lớn:

import numpy as np 
from scipy.ndimage.filters import uniform_filter1d 
N = 1000 
x = np.random.random(100000) 

%timeit pd.rolling_mean(x, window=N) 
__main__:257: FutureWarning: pd.rolling_mean is deprecated for ndarrays and will be removed in a future version 
The slowest run took 84.55 times longer than the fastest. This could mean that an intermediate result is being cached. 
1 loop, best of 3: 7.37 ms per loop 

%timeit uniform_filter1d(x, size=N) 
10000 loops, best of 3: 190 µs per loop 
Các vấn đề liên quan