簡體   English   中英

前向填充Pandas Dataframe水平(沿着行),而不會向前填充每行中的最后一個值

[英]Forward Fill Pandas Dataframe Horizontally (along rows) without forward filling last value in each row

我有一個Pandas數據框,我想轉發填充HORIZONTALLY但我不想轉發填寫每行的最后一個條目。 這是關於某些產品已停產的產品的時間序列定價數據,因此我不希望記錄的最后一個值向前填充到當前。

FWDFILL.apply(lambda series: series.iloc[:,series.last_valid_index()].ffill(axis=1))

^我所包含的代碼做了我想要的但是它是垂直的。 這可能可以幫助人們作為起點。

>>> print(FWDFILL)

1      1     NaN     NaN     2     NaN  
2     NaN     1      NaN     5     NaN  
3     NaN     3       1     NaN    NaN  
4     NaN    NaN     NaN    NaN    NaN  
5     NaN     5      NaN    NaN     1  

期望的輸出:

1      1      1      1     2     NaN  
2     NaN     1      1     5     NaN  
3     NaN     3      1    NaN    NaN  
4     NaN    NaN    NaN   NaN    NaN  
5     NaN     5      5     5      1

在IIUC中,您需要apply axis=1 ,因此您將應用於數據幀行而不是數據幀列。

df.apply(lambda x: x[:x.last_valid_index()].ffill(), axis=1)

輸出:

     1    2    3    4    5
0                         
1  1.0  1.0  1.0  2.0  NaN
2  NaN  1.0  1.0  5.0  NaN
3  NaN  3.0  1.0  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN
5  NaN  5.0  5.0  5.0  1.0

您可以使用numpy查找最后的有效索引並屏蔽您的ffill 這允許您使用矢量化ffill ,然后使用矢量化蒙版。


u = df.values
m = (~np.isnan(u)).cumsum(1).argmax(1)
df.ffill(1).mask(np.arange(df.shape[0]) > m[:, None])

     0    1    2    3    4
0  1.0  1.0  1.0  2.0  NaN
1  NaN  1.0  1.0  5.0  NaN
2  NaN  3.0  1.0  NaN  NaN
3  NaN  NaN  NaN  NaN  NaN
4  NaN  5.0  5.0  5.0  1.0

信息

>>> np.arange(df.shape[0]) > m[:, None]
array([[False, False, False, False,  True],
       [False, False, False, False,  True],
       [False, False, False,  True,  True],
       [False,  True,  True,  True,  True],
       [False, False, False, False, False]])

使用bfillffill

s1=df.ffill(1)
s2=df.bfill(1)
df=df.mask(s1.notnull()&s2.notnull(),s1)
df
Out[222]: 
     1    2    3    4    5
1  1.0  1.0  1.0  2.0  NaN
2  NaN  1.0  1.0  5.0  NaN
3  NaN  3.0  1.0  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN
5  NaN  5.0  5.0  5.0  1.0

或者只是使用interpolate

df.mask(df.interpolate(axis=1,limit_area='inside').notnull(),df.ffill(1))
Out[226]: 
     1    2    3    4    5
1  1.0  1.0  1.0  2.0  NaN
2  NaN  1.0  1.0  5.0  NaN
3  NaN  3.0  1.0  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN
5  NaN  5.0  5.0  5.0  1.0

很少修改 - Most efficient way to forward-fill NaN values in numpy array的解決方案中Most efficient way to forward-fill NaN values in numpy array這里解決它 -

def ffillrows_stoplast(arr):
    # Identical to earlier solution of forward-filling
    mask = np.isnan(arr)
    idx = np.where(~mask,np.arange(mask.shape[1]),0)
    idx_acc = np.maximum.accumulate(idx,axis=1)
    out = arr[np.arange(idx.shape[0])[:,None], idx_acc]

    # Perform flipped index accumulation to get trailing NaNs mask and
    # accordingly assign NaNs there
    out[np.maximum.accumulate(idx[:,::-1],axis=1)[:,::-1]==0] = np.nan
    return out

樣品運行 -

In [121]: df
Out[121]: 
     A    B    C    D    E
1  1.0  NaN  NaN  2.0  NaN
2  NaN  1.0  NaN  5.0  NaN
3  NaN  3.0  1.0  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN
5  NaN  5.0  NaN  NaN  1.0

In [122]: out = ffillrows_stoplast(df.to_numpy())

In [123]: pd.DataFrame(out,columns=df.columns,index=df.index)
Out[123]: 
     A    B    C    D    E
1  1.0  1.0  1.0  2.0  NaN
2  NaN  1.0  1.0  5.0  NaN
3  NaN  3.0  1.0  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN
5  NaN  5.0  5.0  5.0  1.0

我想在ffill上使用where可以回到那些在bfill上被忽略的NaN

df.ffill(1).where(df.bfill(1).notna())    

Out[1623]:
     a    b    c    d    e
1  1.0  1.0  1.0  2.0  NaN
2  NaN  1.0  1.0  5.0  NaN
3  NaN  3.0  1.0  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN
5  NaN  5.0  5.0  5.0  1.0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM