Python 如何在列表中找到将差异返回到前一个零的计数?
我有以下清单 [7,2,0,3,4,2,5,0,3,4] 结果列表是 [1,2,0,1,2,3,4,0,1,2] 通过以下逻辑得到的结果 对于每个值,将差值计算回前一个零(或系列的开始, 以较接近者为准) 我正在尝试实施,但无法实现 那么如何找到之前的零位,这样我们就可以得到这个级数 我在下面尝试过,但不知怎么的,它失败了,而且似乎不是一个好的解决方案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,
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,只有一些pandagroupby
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))]
是的,更简单更好。“解决方案”是什么?认真地