【问题标题】:Create a dataframe - order based on text coordinates创建数据框 - 基于文本坐标的顺序
【发布时间】:2023-02-01 12:58:09
【问题描述】:

我有一个包含多列的数据框(我从pytesseract.image_to_data(img_pl,lang="eng", output_type='data.frame', config='--psm 11') [使用 psm 11 或 12,相同的结果] 得到它并且只从中获取重要的列),让我们看看以下列:

# This is the data I get from the above command,
# I added it like that so you will be able to copy and test it
data = {'left': [154, 154, 200, 154, 201, 199],
        'top': [0, 3, 3, 7, 8, 12],
        'width': [576, 168, 162, 168, 155, 157],
        'height': [89, 10, 10, 10, 10, 10],
        'text': ['text1', 'text2', 'text3', 'text4', 'text5', 'text6']}
output_test_min_agg = pd.DataFrame(data)
# Output:
+----+---+-----+------+-------+
|left|top|width|height|   text|
+----+---+-----+------+-------+
| 154|  0|  576|    89|  text1|
| 154|  3|  168|    10|  text2|
| 200|  3|  162|    10|  text3|
| 154|  7|  168|    10|  text4|
| 201|  8|  155|    10|  text5|
| 199| 12|  157|    10|  text6|
+----+---+-----+------+-------+

请注意,一些坐标偏离了几个像素(从我 看到它最大 3-5 个像素)这就是为什么宽度也可以考虑在内(例如,“abc”和“abcdef”的左侧会有所不同,但我们可以看到宽度达到相同的大小

例外结果如下:

+-----+-------+-------+
|index| col 01| col 02|
+-----+-------+-------+
|    0|  text1|       |
|    1|  text2|  text3|
|    2|  text4|  text5|
|    3|       |  text6|
+-----+-------+-------+

我得到的最好结果是:

output_test_min_agg=output_test_min.sort_values('top', ascending=True)
output_test_min_agg = output_test_min_agg.groupby(['top', 'left'], sort=False)['text'].sum().unstack('left')
output_test_min_agg.reindex(sorted(output_test_min_agg.columns), axis=1).dropna(how='all')

但这仍然不好,因为如果 topleft 有 1 个像素的差异,它将为它们创建一个全新的列和行

我怎样才能完成这样的任务?

【问题讨论】:

  • 你是要解释你是如何从第一张桌子到第二张桌子的,还是我们应该试着猜一猜?
  • 这是我想要的结果,我正在努力实现它,但到目前为止运气为 0,我想找到一种方法从第一个表创建第二个表,我已经做了几个小时,但我仍然没有运气来计算它出去
  • 你应该尽力帮助我们帮助你,我看不出这两张桌子之间有任何联系。为什么第二个是预期的输出
  • 我添加了到目前为止我尝试过的内容,这是我的预期输出我需要这样的表格,我试图根据我拥有的数据找出如何得到这个结果
  • 嗨,不,它们现在不重要,通常数据框的第一行是标题行

标签: python pandas dataframe python-tesseract


【解决方案1】:

您需要根据文本框的位置对文本框进行聚类,如果它们足够接近则合并它们。

import pandas as pd

data = {'left': [154, 154, 200, 154, 201, 199],
        'top': [0, 3, 3, 7, 8, 12],
        'width': [576, 168, 162, 168, 155, 157],
        'height': [89, 10, 10, 10, 10, 10],
        'text': ['text1', 'text2', 'text3', 'text4', 'text5', 'text6']}
output_test_min_agg = pd.DataFrame(data)

output_test_min_agg['left_range'] = output_test_min_agg['left'] + output_test_min_agg['width']

def group_text(df):
    grouped = []
    for i, row in df.iterrows():
        found = False
        for group in grouped:
            if abs(row['top'] - group['top']) <= 5:
                found = True
                group['texts'].append(row['text'])
                group['left_ranges'].append(row['left_range'])
                break
        if not found:
            grouped.append({'top': row['top'], 'texts': [row['text']], 'left_ranges': [row['left_range']]})

    result = []
    for group in grouped:
        left_ranges = sorted(group['left_ranges'])
        texts = [text for _, text in sorted(zip(left_ranges, group['texts']))]
        for i in range(0, len(texts), 2):
            result.append([texts[i], texts[i + 1] if i + 1 < len(texts) else ''])

    return pd.DataFrame(result, columns=['col_01', 'col_02'])

result = group_text(output_test_min_agg)
print(result)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    相关资源
    最近更新 更多