簡體   English   中英

在 pandas 的每一行中,從第一個非 NaN 開始,X 值的 window 保持不變,而所有其他值都是 NaN

[英]In each row of pandas, starting at the first non-NaN a window of X values remains untouched while all other values are NaN

StackOverflow 的公民,

我目前正在對可能有數百萬行長的 dataframe 運行迭代。 在我的 dataframe 的每一行中,我都有前導 NaN(所需),然后是值。 我只想在每行中有 X 個值,然后是 NaN。 實際上,我想要一個只有 X 值的 window,從第一個非 NaN 開始,行中的所有其他位置都是 NaN。

我的解決方案很慢。 此外,我沒有發現類似的問題有足夠的幫助(最關心的只是第一個/最后一個 NaN)。

window 大小為 3 的示例:

import pandas as pd
import numpy as np

x = 3

data = {'2018Q3': [0,   np.nan,   np.nan,      np.nan,      np.nan], 
        '2018Q4': [1,      np.nan,   np.nan,       np.nan,    10],
        '2019Q1': [2,        3,    np.nan,      np.nan, 12],
        '2019Q2': [3,        4,    np.nan,      8,         14],
        '2019Q3': [4,        5,    np.nan,      9,         22]}  

df = pd.DataFrame.from_dict(data) 
print(df)

      2018Q3  2018Q4  2019Q1  2019Q2  2019Q3
0     0.0     1.0     2.0     3.0     4.0
1     NaN     NaN     3.0     4.0     5.0
2     NaN     NaN     NaN     NaN     NaN
3     NaN     NaN     NaN     8.0     9.0
4     NaN    10.0    12.0    14.0    22.0

結果應如下所示:

   2018Q3  2018Q4  2019Q1  2019Q2  2019Q3
0     0.0     1.0     2.0     NaN     NaN
1     NaN     NaN     3.0     4.0     5.0
2     NaN     NaN     NaN     NaN     NaN
3     NaN     NaN     NaN     8.0     9.0
4     NaN    10.0    12.0    14.0     NaN

我的解決方案:

def cut_excess_forecast(num_x, dataf): 
    Total_Col = len(dataf.columns.values) # total columns
    df_NEW = pd.DataFrame()
    for index, row in dataf.iterrows():
        nas = row.isnull().sum(axis =0)  # number of nulls
        good_data = nas +  num_x # gives number of columns that should be untouched
        if good_data >= Total_Col: # if number of columns to not be touched > available columns, pass
            pass # all data available is needed
        else:
            cutoff = Total_Col-good_data 
            row[-cutoff:] = np.nan #change to NaN excess columns in this row

        df_NEW = df_NEW.append(row.copy()) #append changed row to new index
    df_NEW.index = dataf.index #move over original index to the new dataframe
    return df_NEW.copy()

df2 = cut_excess_forecast(x, df)
print(df2)

排序是允許的,只要索引不受影響。 提前歡呼和感謝。

嘗試:

df.where(df.notna().cumsum(1)<4)

Output:

   2018Q3  2018Q4  2019Q1  2019Q2  2019Q3
0     0.0     1.0     2.0     NaN     NaN
1     NaN     NaN     3.0     4.0     5.0
2     NaN     NaN     NaN     NaN     NaN
3     NaN     NaN     NaN     8.0     9.0
4     NaN    10.0    12.0    14.0     NaN

說明

  1. df.notna()False屏蔽NaN值,用True屏蔽非NaN值。
   2018Q3  2018Q4  2019Q1  2019Q2  2019Q3
0    True    True    True    True    True
1   False   False    True    True    True
2   False   False   False   False   False
3   False   False   False    True    True
4   False    True    True    True    True
  1. 使用cumsum(1)的鏈將從左到右計算行上的非NaN值。
   2018Q3  2018Q4  2019Q1  2019Q2  2019Q3
0       1       2       3       4       5
1       0       0       1       2       3
2       0       0       0       0       0
3       0       0       0       1       2
4       0       1       2       3       4
  1. 然后我們比較<4來掩蓋計數超過閾值4False
   2018Q3  2018Q4  2019Q1  2019Q2  2019Q3
0    True    True    True   False   False
1    True    True    True    True    True
2    True    True    True    True    True
3    True    True    True    True    True
4    True    True    True    True   False
  1. 最后將其包裹在np.NaN .where這些單元格。

暫無
暫無

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

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