【问题标题】:Pandas: return index values for first instance and last instance of valuePandas:返回值的第一个实例和最后一个实例的索引值
【发布时间】:2018-05-25 07:21:40
【问题描述】:

我有以下数据框:

df = pd.DataFrame({'index':[0,1,2,3,4,5,6,7,8,9,10], 'X':[0,0,1,1,0,0,1,1,1,0,0]})
df.set_index('index', inplace = True)

   X
index   
0      0
1      0
2      1
3      1
4      0
5      0
6      1
7      1
8      1
9      0
10     0

我需要返回一个元组列表,显示每个 1 序列的 1 的第一个和最后一个实例的索引值(抱歉,如果这令人困惑)。即

想要:

[(2,3), (6,8)]

第一个 1 的第一个实例出现在索引点 2,然后该序列中的最后一个 1 出现在索引点 3。下一个 1 出现在索引点 6,该序列中的最后一个 1 出现在索引点 8 .

我尝试过的:

我可以使用 numpy 的 argmax 函数来获取第一个。即

x1 = np.argmax(df.values)
y1 = np.argmin(df.values[x1:])
(x1,2 + y1 - 1)

这会给我第一个元组,但迭代似乎很乱,我觉得有更好的方法。

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:

    你需要more_itertools.consecutive_groups

    import more_itertools as mit
    def find_ranges(iterable):
        """Yield range of consecutive numbers."""
        for group in mit.consecutive_groups(iterable):
            group = list(group)
            if len(group) == 1:
                yield group[0]
            else:
                yield group[0], group[-1]
    list(find_ranges(df['X'][df['X']==1].index))
    

    输出:

    [(2, 3), (6, 8)]
    

    【讨论】:

      【解决方案2】:

      您可以使用第三方库:more_itertools

      locmit.consecutive_groups

      [list(group) for group in mit.consecutive_groups(df.loc[df.ones == 1].index)]
      
      # [[2, 3], [6, 7, 8]]
      

      简单的列表理解:

      x = [(i[0], i[-1]) for i in x]
      
      #  [(2, 3), (6, 8)]
      

      一种使用numpy的方法,改编自a great answer by @Warren Weckesser

      def runs(a):
          isone = np.concatenate(([0], np.equal(a, 1).view(np.int8), [0]))
          absdiff = np.abs(np.diff(isone))
          ranges = np.where(absdiff == 1)[0].reshape(-1, 2)
          return [(i, j-1) for i, j in ranges]
      
      runs(df.ones.values)
      # [(2, 3), (6, 8)]
      

      【讨论】:

        【解决方案3】:

        这是一个纯粹的 pandas 解决方案:

        df.groupby(df['X'].eq(0).cumsum().mask(df['X'].eq(0)))\
          .apply(lambda x: (x.first_valid_index(),x.last_valid_index()))\
          .tolist()
        

        输出:

        [(2, 3), (6, 8)]
        

        【讨论】:

          猜你喜欢
          • 2015-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-15
          • 2022-01-25
          • 2018-09-05
          • 2022-01-09
          相关资源
          最近更新 更多