【问题标题】:Slicing NaN values before first and after last occurrence for every time series in a pandas dataframe在熊猫数据框中的每个时间序列的第一次和最后一次出现之前和之后切片 NaN 值
【发布时间】:2020-04-10 02:57:45
【问题描述】:

我使用 Python 3 和 Pandas 处理时间序列。我有一个包含多个时间序列的数据框(在本例中为两个),每个时间序列都包含一家商店的销售数据。数据框如下所示:

                  index  Shop  Quantity
index Date                             
0     2017-01-08      0     1       NaN
1     2017-01-15      1     1       NaN
2     2017-01-22      2     1      34.0
3     2017-01-29      3     1      54.0
4     2017-02-05      4     1      42.0
5     2017-02-12      5     1       NaN
6     2017-01-08      6     2       NaN
7     2017-01-15      7     2      29.0
8     2017-01-22      8     2       NaN
9     2017-01-29      9     2      58.0
10    2017-02-05     10     2      49.0
11    2017-02-12     11     2       NaN

对于每个时间序列,我想删除 NaN 直到第一次出现,而 NaN 在最后一次出现后删除。它应该类似于:

                  index  Shop  Quantity
index Date                             
2     2017-01-22      2     1      34.0
3     2017-01-29      3     1      54.0
4     2017-02-05      4     1      42.0
7     2017-01-15      7     2      29.0
8     2017-01-22      8     2       NaN
9     2017-01-29      9     2      58.0
10    2017-02-05     10     2      49.0

但是,以下代码删除了总体第一次出现之前和最后一次出现之后的 NaN,但不删除索引为 5 和 6 的行:

df = df.loc[df['Quantity'].first_valid_index():df['Quantity'].last_valid_index()]
                  index  Shop  Quantity
index Date                             
2     2017-01-22      2     1      34.0
3     2017-01-29      3     1      54.0
4     2017-02-05      4     1      42.0
5     2017-02-12      5     1       NaN
6     2017-01-08      6     2       NaN
7     2017-01-15      7     2      29.0
8     2017-01-22      8     2       NaN
9     2017-01-29      9     2      58.0
10    2017-02-05     10     2      49.0

任何想法如何解决这个问题?感谢您的帮助。

【问题讨论】:

    标签: python pandas dataframe time-series slice


    【解决方案1】:

    用途:

    l = df.index[~(df['Date']>df['Date'].shift())].to_list()
    l.append(len(df))
    l_mod = [0] + l + [max(l)+1]
    list_of_dfs = [df.iloc[l_mod[n]:l_mod[n+1]] for n in range(len(l_mod)-1)]
    
    df_new=pd.DataFrame(columns=df.columns)
    for d in list_of_dfs:
        df_new = df_new.append(d.loc[d['Quantity'].first_valid_index():d['Quantity'].last_valid_index()])
    df_new
    
             Date index.1 Shop  Quantity
    2  2017-01-22       2    1      34.0
    3  2017-01-29       3    1      54.0
    4  2017-02-05       4    1      42.0
    7  2017-01-15       7    2      29.0
    8  2017-01-22       8    2       NaN
    9  2017-01-29       9    2      58.0
    10 2017-02-05      10    2      49.0
    

    【讨论】:

      【解决方案2】:

      让我们将groupbyfirst_valid_indexlast_valid_index 与使用loc 的索引切片一起使用:

      df.groupby('Shop', group_keys=False)\
        .apply(lambda x: x.loc[x['Quantity'].first_valid_index():x['Quantity'].last_valid_index()])
      

      输出:

                        ind  Shop  Quantity
      index Date                           
      2     2017-01-22    2     1      34.0
      3     2017-01-29    3     1      54.0
      4     2017-02-05    4     1      42.0
      7     2017-01-15    7     2      29.0
      8     2017-01-22    8     2       NaN
      9     2017-01-29    9     2      58.0
      10    2017-02-05   10     2      49.0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多