Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在列表中找到将差异返回到前一个零的计数?_Python_Algorithm_Pandas_Dataframe_Recursive Datastructures - Fatal编程技术网

Python 如何在列表中找到将差异返回到前一个零的计数?

Python 如何在列表中找到将差异返回到前一个零的计数?,python,algorithm,pandas,dataframe,recursive-datastructures,Python,Algorithm,Pandas,Dataframe,Recursive Datastructures,我有以下清单 [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,

我有以下清单

[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)
将熊猫作为pd导入
数据帧({'X':[7,2,0,3,4,2,5,0,3,4]})
#打印(df)
df_系列=df['X']
打印(df_series.iloc[-1])
目标_系列=pd系列([])
#打印(target_系列)
def计算_值(i,实际_指数):
如果(df_series.iloc[i-1]==0):
如果(i<0):
零位=i+df_系列。尺寸-1
如果(实际指数-0<零位置):
目标指数系列[实际指数]=实际指数+1
返回
其他:
目标_系列[实际_指数]=零位置
返回
其他:
目标系列[实际指数]=目标系列[实际指数]+1
返回
其他:
如果(i+df_series.size!=实际_索引):
计算_值(i-1,实际_指数)
对于df.index中的i:
如果(df_系列[i]=0和i!=0):
目标_系列[i]=0
elif(df_系列[i]!=0和i==0):
目标_系列[i]=1
其他:
计算_值(i,i)
打印(target_系列)

以下是一个可行的解决方案:

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]

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

以下是如何使用标准列表,而不是数据帧,但逻辑是相同的

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)
您可以看到代码正在工作

一些解释:

您需要的是数组中两个
0
之间的一种
计数器。

因此,您在数组上循环,每次遇到
0
时,您都会重置计数器,并在循环的每次迭代中插入计数器的值。

如果您坚持使用列表,您可以非常轻松地获得结果:

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]

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

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]

如果您只想使用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)
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()

b
是必需的列表。

解决方案没有for循环或apply,只有一些panda
groupby
fun

我们使用

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
正向填充添加一个是从中提取的。

如果您想要一个一行解决方案:

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)
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]

为什么要使用pandas/dataframe标记?更简单/更短的方法:
[(a[i:-1]+[0])。索引(0)表示范围内的i(len(a))]
是的,更简单更好。“解决方案”是什么?认真地