簡體   English   中英

在pandas數據幀中寫一個用戶定義的fillna函數,用條件填充np.nan不同的值

[英]Write a user defined fillna function in pandas dataframe to fill np.nan different values with conditions

考慮以下pandas數據幀:

import pandas as pd

change = [0.475, 0.625, 0.1, 0.2, -0.1, -0.75, 0.1, -0.1, 0.2, -0.2]
position = [1.0, 1.0, nan, nan, nan, -1.0, nan, nan, nan, nan]
date = ['20150101', '20150102', '20150103', '20150104', '20150105', '20150106', '20150107', '20150108', '20150109', '20150110']
pd.DataFrame({'date': date, 'position': position, 'change': change})

輸出

     date        change       position    
    20150101      0.475          1
    20150102      0.625          1
    20150103      0.1            np.nan
    20150104      0.2            np.nan
    20150105      -0.1           np.nan
    20150106      -0.75          -1
    20150107      0.1            np.nan
    20150108      -0.1           np.nan
    20150109      0.2            np.nan
    20150110      -0.2           np.nan

我想用以下規則填寫:

  1. 對於“position”值為np.nan的行,如果“change”的值與position的最后一個非null值具有相同的符號(change * position> 0,例如0.1 * 1和0.2 * 1> 0),我們用最后一個非空值填充。

  2. 對於“position”值為np.nan的行,如果“change”的值與position的最后一個非null值相同的符號(change * position <= 0,如-1 * 0.1),則填充為0 。

  3. 一旦np.nan填充0,則以下np.nan也將填充0。

以下是樣本數據框的預期結果:

     date        change       position    
    20150101      0.475          1
    20150102      0.625          1
    20150103      0.1            1
    20150104      0.2            1
    20150105      -0.1           0
    20150106      -0.75          -1
    20150107      0.1            0
    20150108      -0.1           0
    20150109      0.2            0
    20150110      -0.2           0

編輯:

我開發的方法如下:

while(any(np.isnan(x['position']))):
    conditions = [(np.isnan(x['position'])) & (x['position'].shift(1) * x['change'] > 0),
                  (np.isnan(x['position'])) & (x['position'].shift(1) * x['change'] <= 0)]
    choices = [x['position'].shift(1), 0]
    x['position'] = np.select(conditions, choices, default=x['position'])

但正如你所看到的,它不是很令人滿意,而且如果你有80,000,000行數據則非常慢。

有什么建議? 謝謝您的幫助!

我認為你的代碼非常可靠,主要問題是你需要多次迭代它。 shift()只返回一行,但是如果你把它fillna(method='ffill')那么你基本上得到一個無限制的移位數但只需要做一次而不是多次迭代(如何許多迭代將取決於您的數據)。

conditions = [
    (np.isnan(x['position'])) & (x['position'].fillna(method='ffill')*x['change']>0),
    (np.isnan(x['position'])) & (x['position'].fillna(method='ffill')*x['change']<=0)]

但我相信你可以更進一步,通過在最后添加另一個fillna消除while

conditions = [
    (np.isnan(x['position'])) & (x['position'].fillna(method='ffill')*x['change']>0),
    (np.isnan(x['position'])) & (x['position'].fillna(method='ffill')*x['change']<=0)]

choices=[x['position'].shift(1),0]
x['position'] = np.select(conditions,choices,default=x['position'])

x['position'] = x['position'].fillna(method='ffill')

在您的示例數據上,第一次更改比您的代碼快2倍,第二次更改大約是4倍。 我得到了與你相同的答案,但當然你會想要在真實數據上驗證這一點。

暫無
暫無

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

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