【问题标题】:how to find the count the difference back to the previous zero in a list?如何找到计数差异回到列表中的前一个零?
【发布时间】:2018-01-24 13:11:41
【问题描述】:

我有以下列表

[7, 2, 0, 3, 4, 2, 5, 0, 3, 4]

结果列表是

[1, 2, 0, 1, 2, 3, 4, 0, 1, 2]

用下面的逻辑得到的结果

对于每个值,将差值计算回前一个零(或系列的开头, 以更近者为准)。

我正在尝试实施,但无法获得。

那么如何找到之前的零位,从而得到那个系列呢?

我在下面尝试过,但不知何故失败了,这似乎不是一个好的解决方案

import pandas as pd



df = pd.DataFrame({'X': [7, 2, 0, 3, 4, 2, 5, 0, 3, 4]})

#print(df)

df_series = df['X']

print(df_series.iloc[-1])

target_series = pd.Series([])

#print(target_series)

def calculate_value(i,actual_index): 
    if(df_series.iloc[i-1] == 0):
        if(i < 0):
            zero_position = i + df_series.size-1
            if(actual_index - 0 < zero_position):
                target_series[actual_index]=actual_index+1
                return
            else:
                target_series[actual_index]=zero_position
                return
        else:
            target_series[actual_index]=target_series[actual_index]+1
            return
    else:
        if(i+df_series.size != actual_index):   
            calculate_value(i-1,actual_index)


for i in df.index:
    if(df_series[i]==0 and i!=0):
        target_series[i]=0
    elif(df_series[i]!=0 and i==0):
        target_series[i]=1
    else:
        calculate_value(i,i)


print(target_series)

【问题讨论】:

  • 为什么是 pandas/ 数据框标签?

标签: python algorithm pandas dataframe recursive-datastructures


【解决方案1】:

如果您想要 Pandas 单线解决方案:

import pandas as pd

s = pd.Series([7, 2, 0, 3, 4, 2, 5, 0, 3, 4])

(s.groupby(s.eq(0).cumsum().mask(s.eq(0))).cumcount() + 1).mask(s.eq(0), 0).tolist()

输出:

[1, 2, 0, 1, 2, 3, 4, 0, 1, 2]

【讨论】:

    【解决方案2】:

    如果你坚持列表,你可以很容易地得到你的结果:

    l = [7, 2, 0, 3, 4, 2, 5, 0, 3, 4]
    i = 0
    r = []
    
    for element in l:
        if element != 0:
            i += 1
        else:
            i = 0
        r.append(i)
    r
    #[1, 2, 0, 1, 2, 3, 4, 0, 1, 2]
    

    【讨论】:

      【解决方案3】:

      这里有一个适合您的解决方案:

      a = [7, 2, 0, 3, 4, 2, 5, 0, 3, 4]
      
      b = []
      z_pos = -1
      for i, n in enumerate(a):
          if n == 0:
              z_pos = i
          b.append(i - z_pos)
      print(b)  # [1, 2, 0, 1, 2, 3, 4, 0, 1, 2]
      

      它没有使用任何太花哨的东西,所以我认为没有必要解释它的内部工作原理。但是,如果您有不清楚的地方,请告诉我。

      【讨论】:

        【解决方案4】:

        如果你只想使用python,这里是解决方案:

        a = [7, 2, 0, 3, 4, 2, 5, 0, 3, 4]
        z = None
        b = []
        for i in range(len(a)):
            if a[i] != 0 and z== None:
                b.append(i+1)
            elif a[i] == 0:
                b.append(0)
                z = 0
            else:
                z += 1
                b.append(z)
        

        b 是必需的列表。

        【讨论】:

        • “那个”解决方案?认真的吗?
        【解决方案5】:

        这里是如何使用标准列表而不是 Pandas 数据框,但逻辑是一样的

        arr = [7,2,0,3,4,5,1,0,2]
        arr2 = []
        counter = 1
        for item in arr:
            if(item==0):
              counter = 0
        
            arr2.append(counter)
            counter+=1
        
        print(arr2)
        

        你可以看到代码在here工作。

        一些解释:

        您想要的是数组中两个0 之间的counter。 因此,您循环遍历数组,每次遇到0 时都会重置计数器,并在每次循环迭代时插入计数器的值。

        【讨论】:

          【解决方案6】:

          如果你喜欢简洁而不是可读性或有效性,你也可以使用这个:

          a = [7, 2, 0, 3, 4, 2, 5, 0, 3, 4]
          distances = [([0]+a)[:idx][::-1].index(0) for idx in range(1, len(a)+2)][1:]
          

          这给出了预期的结果:

          print(distances)
          >> [1, 2, 0, 1, 2, 3, 4, 0, 1, 2]
          

          【讨论】:

          • 更简单/更短的方法:[(a[i::-1]+[0]).index(0) for i in range(len(a))]
          • 是的,更简单更好。
          【解决方案7】:

          没有 for 循环或应用的解决方案,只是一些 pandas groupby 有趣。

          我们使用

          df = pd.DataFrame({'X': [7, 2, 0, 3, 4, 2, 5, 0, 3, 4]})
          
          # make a new column with zeros at zeros and nans elsewhere
          df = df.assign(idx_from_0=df.loc[df.X==0])
          
          nul = df['idx_from_0'].isnull()
          df.assign(idx_from_0=nul.groupby((nul.diff() == 1).cumsum()).cumsum())
          
          Out[1]:
              X   idx_from_0
          0   7   1.0
          1   2   2.0
          2   0   0.0
          3   3   1.0
          4   4   2.0
          5   2   3.0
          6   5   4.0
          7   0   0.0
          8   3   1.0
          9   4   2.0
          

          cumsum 前向填充加一取自 this answer

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-08-25
            • 1970-01-01
            • 1970-01-01
            • 2019-11-23
            • 2013-01-02
            • 2013-03-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多