2015-07-10 13 views
6

Khi sử dụng gấu trúc suy() để điền NaN đánh giá cao như thế này:Pandas suy thay thế Nans sau khi các điểm dữ liệu cuối cùng, nhưng không phải trước khi các điểm dữ liệu đầu tiên

In [1]: s = pandas.Series([np.nan, np.nan, 1, np.nan, 3, np.nan, np.nan]) 

In [2]: s.interpolate() 
Out[2]: 
0 NaN 
1 NaN 
2  1 
3  2 
4  3 
5  3 
6  3 
dtype: float64 

In [3]: pandas.version.version 
Out[3]: '0.16.2' 

, tại sao gấu trúc thay thế các giá trị tại chỉ số 5 và 6 với 3s, nhưng để các giá trị ở 0 và 1 như là?

Tôi có thể thay đổi hành vi này không? Tôi muốn loại bỏ NaN tại chỉ số 5 và 6.

(Thực ra, tôi muốn nó làm ngoại suy tuyến tính để điền vào tất cả 0, 1, 5 và 6, nhưng đó là một câu hỏi khác. Điểm thưởng nếu bạn cũng trả lời!)

Trả lời

5

Phương pháp nội bộ, interpolate sử dụng thông số 'giới hạn' tránh tuyên truyền điền nhiều hơn ngưỡng cụ thể.

>>>df=pd.DataFrame([0, np.nan, np.nan, np.nan, np.nan,np.nan, 2]) 
>>>df 
df 
    0 
0 0 
1 NaN 
2 NaN 
3 NaN 
4 NaN 
5 NaN 
6 2 
>>>df.interpolate(limit=2) 
      0 
0 0.000000 
1 0.333333 
2 0.666667 
3  NaN 
4  NaN 
5  NaN 
6 2.000000 

Theo mặc định, giới hạn được áp dụng theo hướng chuyển tiếp. Theo hướng ngược lại, có giới hạn mặc định được đặt thành 0. Đây là lý do tại sao các bước đầu tiên của bạn không được điền bằng phương thức. Người ta có thể thay đổi hướng bằng cách sử dụng tham số 'limit_direction'.

df.interpolate(limit=2, limit_direction='backward') 
      0 
0 0.000000 
1  NaN 
2  NaN 
3  NaN 
4 1.333333 
5 1.666667 
6 2.000000 

Để lấp đầy những bước đầu tiên và những bước cuối cùng của dataframe của bạn, bạn có thể nên thiết lập một tổ chức phi zero giá trị cho 'giới hạn' và 'limit_direction' thành 'cả hai':

>>> df=pd.DataFrame([ np.nan, np.nan, 0, np.nan, 2, np.nan,8,5,np.nan, np.nan]) 
>>> df 
    0 
0 NaN 
1 NaN 
2 0 
3 NaN 
4 2 
5 NaN 
6 8 
7 5 
8 NaN 
9 NaN 
>>> df.interpolate(method='spline', order=1, limit=10, limit_direction='both') 
      0 
0 -3.807382 
1 -2.083581 
2 0.000000 
3 1.364022 
4 2.000000 
5 4.811625 
6 8.000000 
7 5.000000 
8 4.937632 
9 4.138735 

Các chủ đề đã được thảo luận here

+0

Bạn có nghĩ rằng có một sự khác biệt giữa việc sử dụng limit_direction = 'cả hai' (với giới hạn = Không) và sử dụng ngoại suy, như được thực hiện ở đây cho instace (https://stackoverflow.com/questions/22491628/extrapolate-values-in-pandas -khung dữ liệu) ? –

2

Hành vi interpolate trong gấu trúc này có vẻ kỳ lạ. Bạn có thể sử dụng scipy.interpolate.interp1d để tạo ra kết quả mong đợi. Đối với phép ngoại suy tuyến tính, một hàm đơn giản có thể được viết để thực hiện tác vụ này.

import pandas as pd 
import numpy as np 
import scipy as sp 

s = pd.Series([np.nan, np.nan, 1, np.nan, 3, np.nan, np.nan]) 

# interpolate using scipy 
# =========================================== 
s_no_nan = s.dropna() 
func = sp.interpolate.interp1d(s_no_nan.index.values, s_no_nan.values, kind='linear', bounds_error=False) 
s_interpolated = pd.Series(func(s.index), index=s.index) 

Out[107]: 
0 NaN 
1 NaN 
2  1 
3  2 
4  3 
5 NaN 
6 NaN 
dtype: float64 

# extrapolate using user-defined func 
# =========================================== 
def my_extrapolate_func(scipy_interpolate_func, new_x): 
    x1, x2 = scipy_interpolate_func.x[0], scipy_interpolate_func.x[-1] 
    y1, y2 = scipy_interpolate_func.y[0], scipy_interpolate_func.y[-1] 
    slope = (y2 - y1)/(x2 - x1) 
    return y1 + slope * (new_x - x1) 

s_extrapolated = pd.Series(my_extrapolate_func(func, s.index.values), index=s.index) 

Out[108]: 
0 -1 
1 0 
2 1 
3 2 
4 3 
5 4 
6 5 
dtype: float64 
+0

Cảm ơn. Tôi vẫn hy vọng ai đó sẽ trả lời với một lời giải thích về những gì đang xảy ra với gấu trúc. Nó chỉ cần được gói scipy ... – foobarbecue

+0

scipy gói sẽ có nghĩa là gấu trúc có một phụ thuộc vào scipy, mà tôi đoán họ muốn tránh. – Jezzamon

+0

@foobarbecue bạn đã bao giờ tìm ra điều này? Tôi nhận được vấn đề tương tự với gấu trúc 0.18.1 – toasteez

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