如何将 scikit 图像轮廓存储在具有单个顶点和每行轮廓数的 Pandas DataFrame 中
How to store scikit-image contours in a Pandas DataFrame with a single vertex and a contour number per row
我正在使用 this scikit-image demo 的修改版本从图像的分水岭分割产生的边缘创建轮廓。在这个结果中,每一层只有一个轮廓,由行列索引对组成。
像演示中那样显示轮廓很容易。但我想做的是使用 enumerate
循环将每个轮廓的每个顶点附加到 Pandas DataFrame,分隔行和列索引,然后添加一个 level/contour 索引在单独的专栏中。
为了说明,我将从一个小玩具示例开始,其中每个轮廓只有一个索引。使用此代码:
np.random.seed(131)
test = np.random.randint(50, size=5)
n_list = []
t_list = []
for n, t in enumerate(test):
n_list.append(n)
t_list.append(t)
contours_df = pd.DataFrame({'contour': n_list, 'contour': t_list})
contours_df
我得到这个 DataFrame:
比较有代表性的例子是这样的:
np.random.seed(131)
test1 = np.random.randint(50, size=(5, 2, 2))
n_list1 = []
t_list1 = []
for n1, t1 in enumerate(test1):
n_list1.append(n1)
t_list1.append(t1)
contours_df1 = pd.DataFrame({'contour': n_list1, 'points': t_list1})
contours_df1
这给了我这个 DataFrame:
我可以使用 XlsxWriter
将其导出到 Excel 文件,如下所示:
# using XlsxWriter documentation example
writer = pd.ExcelWriter('contours_df1.xlsx', engine='xlsxwriter')
contours_df1.to_excel(writer, sheet_name='Sheet1')
writer.save()
得到这个:
但我真正想要的是拆分轮廓以获得类似这样的最终 Excel 输出:
您快要达到目标了,您只需要稍微玩一下:
enumerate
方法按预期工作。当我们枚举一个可迭代的 python 对象时,我们得到对象元素和 "pointer" 之间的 1-1
相关性,范围从 0
到 len(iterable_object)-1
.
从文档中查看此示例:
>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
现在实现您在这里向我们展示的内容的一种方法是使用从 enumerate
生成的指针 2 次并相应地拆分每个 test
元素的内容:
np.random.seed(131)
test1 = np.random.randint(50, size=(5, 2, 2))
contour_lst = []
row_lst = []
column_lst = []
for n, t_elem in enumerate(test1):
# First square coordinates for this contour.
contour_lst.append(n)
row_lst.append(t_elem[0][0])
column_lst.append(t_elem[0][1])
# Second square coordinates for this contour.
contour_lst.append(n)
row_lst.append(t_elem[1][0])
column_lst.append(t_elem[1][1])
contours_df1 = pd.DataFrame({
'contour': contour_lst,
'row': row_lst,
'column': column_lst,
})
我会使用 pandas 串联。对于大小合理的数据,是否为每列构建一个列表取决于个人喜好(尽管您需要第二个嵌套循环以允许任意大小的轮廓)。对于更大的数据,我认为这种方法应该更快,因为它在可能的情况下使用 NumPy/pandas 向量化。
这是一个例子:
import numpy as np
import pandas as pd
contours = [np.random.random((i, 2)
for i in np.random.randint(3, 10, size=5)]
dataframes = []
for contour_id, contour in enumerate(contours):
current_dataframe = pd.DataFrame(contour, columns=['row', 'column'])
current_dataframe['contour'] = contour_id
dataframes.append(current_dataframe)
contours_data = pd.concat(dataframes)
contours_data.to_excel('filename.xlsx', sheet_name='Sheet1')
旁注:如果您只写一个 sheet.
,则不需要创建 ExcelWriter
我正在使用 this scikit-image demo 的修改版本从图像的分水岭分割产生的边缘创建轮廓。在这个结果中,每一层只有一个轮廓,由行列索引对组成。
像演示中那样显示轮廓很容易。但我想做的是使用 enumerate
循环将每个轮廓的每个顶点附加到 Pandas DataFrame,分隔行和列索引,然后添加一个 level/contour 索引在单独的专栏中。
为了说明,我将从一个小玩具示例开始,其中每个轮廓只有一个索引。使用此代码:
np.random.seed(131)
test = np.random.randint(50, size=5)
n_list = []
t_list = []
for n, t in enumerate(test):
n_list.append(n)
t_list.append(t)
contours_df = pd.DataFrame({'contour': n_list, 'contour': t_list})
contours_df
我得到这个 DataFrame:
比较有代表性的例子是这样的:
np.random.seed(131)
test1 = np.random.randint(50, size=(5, 2, 2))
n_list1 = []
t_list1 = []
for n1, t1 in enumerate(test1):
n_list1.append(n1)
t_list1.append(t1)
contours_df1 = pd.DataFrame({'contour': n_list1, 'points': t_list1})
contours_df1
这给了我这个 DataFrame:
我可以使用 XlsxWriter
将其导出到 Excel 文件,如下所示:
# using XlsxWriter documentation example
writer = pd.ExcelWriter('contours_df1.xlsx', engine='xlsxwriter')
contours_df1.to_excel(writer, sheet_name='Sheet1')
writer.save()
得到这个:
但我真正想要的是拆分轮廓以获得类似这样的最终 Excel 输出:
您快要达到目标了,您只需要稍微玩一下:
enumerate
方法按预期工作。当我们枚举一个可迭代的 python 对象时,我们得到对象元素和 "pointer" 之间的 1-1
相关性,范围从 0
到 len(iterable_object)-1
.
从文档中查看此示例:
>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter'] >>> list(enumerate(seasons)) [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
现在实现您在这里向我们展示的内容的一种方法是使用从 enumerate
生成的指针 2 次并相应地拆分每个 test
元素的内容:
np.random.seed(131)
test1 = np.random.randint(50, size=(5, 2, 2))
contour_lst = []
row_lst = []
column_lst = []
for n, t_elem in enumerate(test1):
# First square coordinates for this contour.
contour_lst.append(n)
row_lst.append(t_elem[0][0])
column_lst.append(t_elem[0][1])
# Second square coordinates for this contour.
contour_lst.append(n)
row_lst.append(t_elem[1][0])
column_lst.append(t_elem[1][1])
contours_df1 = pd.DataFrame({
'contour': contour_lst,
'row': row_lst,
'column': column_lst,
})
我会使用 pandas 串联。对于大小合理的数据,是否为每列构建一个列表取决于个人喜好(尽管您需要第二个嵌套循环以允许任意大小的轮廓)。对于更大的数据,我认为这种方法应该更快,因为它在可能的情况下使用 NumPy/pandas 向量化。
这是一个例子:
import numpy as np
import pandas as pd
contours = [np.random.random((i, 2)
for i in np.random.randint(3, 10, size=5)]
dataframes = []
for contour_id, contour in enumerate(contours):
current_dataframe = pd.DataFrame(contour, columns=['row', 'column'])
current_dataframe['contour'] = contour_id
dataframes.append(current_dataframe)
contours_data = pd.concat(dataframes)
contours_data.to_excel('filename.xlsx', sheet_name='Sheet1')
旁注:如果您只写一个 sheet.
,则不需要创建 ExcelWriter