[英]Converting a 3D numpy array to coordinates and values
我有一个形状为 (7,100,50) 的 3D numpy 数组,代表 7 张 100x50 图像的堆栈。
我想将此数组转换为包含所有像素 x、y、z 的位置和像素值 (id) 的数据帧
我已经设法为单个图像执行此操作(无 z):
import numpy as np
import pandas as pd
img = np.random.randint(0,30,size=(100,50))
cell_id = img.flatten()
x = [i % img.shape[1] for i in range(len(cell_id))]
y = [y_ for y_ in range(img.shape[1]) for _ in range(img.shape[0])]
df = pd.DataFrame(data={"id":cell_id, "x":x, "y":y, "z":0})
df:
id x y z
0 29 0 0 0
1 16 1 0 0
2 3 2 0 0
3 15 3 0 0
4 23 4 0 0
... ... ... ... ...
4995 7 45 49 0
4996 6 46 49 0
4997 1 47 49 0
4998 5 48 49 0
4999 7 49 49 0
5000 rows × 4 columns
我该如何调整它以适用于
zimg = np.random.randint(0,30,size=(7,100,50))
?
import numpy as np
import pandas as pd
img = np.random.randn(7,100,50) # (z,x,y)
mapping = {
'x': [],
'y': [],
'z': [],
'id': [],
}
for z in range(7):
for x in range(100):
for y in range(50):
mapping['x'].append(x)
mapping['y'].append(y)
mapping['z'].append(z)
mapping['id'].append(img[z][x][y])
df = pd.DataFrame.from_dict(mapping)
df.head()
或者你可以做你刚才做的 7 次,z 值会改变并且只是使用 pd.concat 连接每个表
我看到你在另一条评论中提到np.ndenumerate
,这应该可以解决问题:
import pandas as pd
import numpy as np
def constructor(array, z=0):
"""Transform an array into df
Here we assume z=0 as in your example
"""
for (img_id, y, x), value in np.ndenumerate(array):
yield (img_id, value, x, y, z)
a = np.random.randint(0,30,size=(7,100,50))
df = pd.DataFrame(
constructor(a),
columns=('image_id', 'id', 'x', 'y', 'z')
)
我将采用相同的形状,但尺寸较小 (2,10,5),以便输出易于解释,并且代码可以在我正在验证的在线编译器上运行。 您可以提供 (7,100,50) 的原始大小。
import numpy as np
import pandas as pd
x = np.random.randint(0,30,size=(2,10,5))
x[x==0] = -1 #replace 0 with -1 to use np.nonzero
val = np.transpose(np.nonzero(x)) #get pixel indices as 2d array
id = x[np.nonzero(x)] #get pixels as 1d array
df = pd.DataFrame.from_records(val) #create df
df = df.set_index(id) #set new index
df.columns = ['x','y', 'z'] #set column names
df.index.name = 'id' #set index column name
df = df.reset_index() #reset index to get id as column
df = df.clip(lower=0) #replace -1 in id with 0
print(df.head(100))
输出:
id x y z
0 6 0 0 0
1 17 0 0 1
2 19 0 0 2
3 26 0 0 3
4 12 0 0 4
.. .. .. .. ..
95 16 1 9 0
96 26 1 9 1
97 8 1 9 2
98 5 1 9 3
99 13 1 9 4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.