将3D numpy数组转换为坐标和值

ctzwtxfj  于 2022-12-23  发布在  其他
关注(0)|答案(3)|浏览(163)

我有一个shape的3D numpy数组(7,100,50),它表示一个由7个100x50图像组成的堆栈。
我想把这个数组转换成一个 Dataframe ,包含所有像素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))

kwvwclae

kwvwclae1#

我看到你在另一条评论中提到了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')
)
jecbmhm3

jecbmhm32#

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连接每个表

eivnm1vs

eivnm1vs3#

我将采取相同的形状,但较小的大小(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

相关问题