Python 如果没有另一个数组,则通过重复值来扩展该数组
我正在使用TrackPy插件跟踪平面上的一些粒子。这将产生一个在x和y中具有位置和相应帧号的数据帧,这里通过一个简单列表进行说明:Python 如果没有另一个数组,则通过重复值来扩展该数组,python,arrays,pandas,sorting,numpy,Python,Arrays,Pandas,Sorting,Numpy,我正在使用TrackPy插件跟踪平面上的一些粒子。这将产生一个在x和y中具有位置和相应帧号的数据帧,这里通过一个简单列表进行说明: x=[80.1,80.2,80.1,80.2,80.3] y=[40.1,40.2,40.1,40.2,40.3] frame = [1,2,3,4,5] 但是,由于实验设置,可能会丢失单个帧的粒子,从而导致: x=[80.1,80.2,80.1,80.2,80.3] y=[40.1,40.2,40.1,40.2,40.3] frame = [1,2,3,4,6]
x=[80.1,80.2,80.1,80.2,80.3]
y=[40.1,40.2,40.1,40.2,40.3]
frame = [1,2,3,4,5]
但是,由于实验设置,可能会丢失单个帧的粒子,从而导致:
x=[80.1,80.2,80.1,80.2,80.3]
y=[40.1,40.2,40.1,40.2,40.3]
frame = [1,2,3,4,6]
现在,我想扩展所有列表,这样“frame”将继续,如果原始数据中没有帧,那么“x,y”将重复前面的值,从而产生如下结果:
x=[80.1,80.2,80.1,80.2,80,2,80.3]
y=[40.1,40.2,40.1,40.2,40.2,40.3]
frame = [1,2,3,4,5,6]
您可以使用Pandas,它在内部使用NumPy阵列:
import pandas as pd
df = pd.DataFrame({'x': x, 'y': y}, index=frame)
df = df.reindex(np.arange(df.index.min(), df.index.max()+1)).ffill()
结果
print(df)
x y
1 80.1 40.1
2 80.2 40.2
3 80.1 40.1
4 80.2 40.2
5 80.2 40.2
6 80.3 40.3
然后,您可以将结果提取到列表中:
x = df['x'].tolist()
y = df['y'].tolist()
frame = df.index.tolist()
这里有一个基于NumPy的解决方案-
def extend_arrs(x,y,frame):
# Convert to arrays
frame = np.asarray(frame)
x = np.asarray(x)
y = np.asarray(y)
l = frame[-1]-frame[0] + 1
id_ar = np.zeros(l,dtype=int)
id_ar[frame-frame[0]] = 1
idx = id_ar.cumsum()-1
return np.r_[frame[0]:frame[-1]+1],x[idx], y[idx]
样本运行-
In [164]: x
Out[164]: [80.1, 80.2, 80.1, 80.2, 80.3]
In [165]: y
Out[165]: [40.1, 40.2, 40.1, 40.2, 40.3]
In [166]: frame = [5,6,8,11,13]
In [167]: extend_arrs(x,y,frame)
Out[167]:
(array([ 5, 6, 7, 8, 9, 10, 11, 12, 13]),
array([80.1, 80.2, 80.2, 80.1, 80.1, 80.1, 80.2, 80.2, 80.3]),
array([40.1, 40.2, 40.2, 40.1, 40.1, 40.1, 40.2, 40.2, 40.3]))
# Output in tabular format for quick reference
In [168]: np.c_[extend_arrs(x,y,frame)]
Out[168]:
array([[ 5. , 80.1, 40.1],
[ 6. , 80.2, 40.2],
[ 7. , 80.2, 40.2],
[ 8. , 80.1, 40.1],
[ 9. , 80.1, 40.1],
[10. , 80.1, 40.1],
[11. , 80.2, 40.2],
[12. , 80.2, 40.2],
[13. , 80.3, 40.3]])
Numpy和diff
使用diff
计算我们需要重复多少次
作用
示范
您的帧始终从1开始?不,通常会从1开始,但可以从任何整数开始。
def ext_pir(x, y, frame):
x, y, frame = map(np.asarray, [x, y, frame])
mn, mx = frame.min(), frame.max() + 1
d = np.diff(np.append(frame, mx))
r = np.arange(len(frame))
i = r.repeat(d)
return x[i], y[i], np.arange(mn, mx)
x = [80.1, 80.2, 80.1, 80.2, 80.3]
y = [40.1, 40.2, 40.1, 40.2, 40.3]
frame = [1, 2, 3, 4, 6]
print("Inputs")
print(*map(np.asarray, (x, y, frame)), sep='\n')
print()
print("Outputs")
print(*ext_pir(x, y, frame), sep='\n')
Inputs
[80.1 80.2 80.1 80.2 80.3]
[40.1 40.2 40.1 40.2 40.3]
[1 2 3 4 6]
Outputs
[80.1 80.2 80.1 80.2 80.2 80.3]
[40.1 40.2 40.1 40.2 40.2 40.3]
[1 2 3 4 5 6]
x = [80.1, 80.2, 80.1, 80.2, 80.3]
y = [40.1, 40.2, 40.1, 40.2, 40.3]
frame = [5, 6, 8, 11, 13]
print("Inputs")
print(*map(np.asarray, (x, y, frame)), sep='\n')
print()
print("Outputs")
print(*ext_pir(x, y, frame), sep='\n')
Inputs
[80.1 80.2 80.1 80.2 80.3]
[40.1 40.2 40.1 40.2 40.3]
[ 5 6 8 11 13]
Outputs
[80.1 80.2 80.2 80.1 80.1 80.1 80.2 80.2 80.3]
[40.1 40.2 40.2 40.1 40.1 40.1 40.2 40.2 40.3]
[ 5 6 7 8 9 10 11 12 13]