如何使用python计算数据框值之间的范围

时间:2019-03-07 10:42:18

标签: python pandas dataframe

在我的数据框中,有一列需求和结果。所以我的目标是要得到一个逻辑,以便我可以确定需求中给出的范围,并将其与结果进行比较,然后说出它的“确定”还是“不合适”。

这是我的excel屏幕截图。

enter image description here

这只是excel的一小幅屏幕截图。

因此,如果该值在该范围内,则结果列将显示为“ 确定”;如果该值不在该范围内,则将显示“ 不正确” “

反正我可以通过在python中使用熊猫来完成此工作吗? 请帮忙! 问我问题是否不清楚。

import pandas as pd
import numpy as np
import csv
from tabulate import tabulate

df = pd.read_csv('Form3.tsv',delimiter='\t')

df = df.loc[df['level'] == 5]
df = df.dropna(subset=['text'])
df = df.loc[df['top'] > 500]
df = df.loc[df['conf'] != 0]
df = df[df['text'].notnull()]
df = df[df['text'] != ' ']
column_separator = 0

distinct_pages = df.page_num.unique()
#print("Distinct pages in file are ",distinct_pages)
df.sort_values(['page_num','line_num','word_num'])
all_rows = []

for each_page in distinct_pages:
    df_each_page = df.loc[df['page_num'] == each_page]
    #print(df_each_page)
    char_num = []
    line_num = []
    ref_loc = []
    charateristic_designator = []
    results = []
    requirement_for_each_line = []
    each_row = []
    current_line_left = 0
    previous_line_left = 1000
    previous_line_width = 1000
    previous_line_number = 1
    line_flag = False
    result_flag = False
    requirement = []
    resultText = ''
    char_num_text = ''
    ref_loc_text = ''
    charateristic_designator_text = ''
    for index, row in df_each_page.iterrows():
        column_separator = 0
        word_num = row['word_num']
        text = row['text']
        Minor_flag = False
        requirement_flag = False
        current_line_number = row['line_num']
        if current_line_number == previous_line_number:
            line_flag = False
        if current_line_number != previous_line_number:
            line_flag = True
            previous_line_number = current_line_number
        current_line_left = row['left']
        column_separator = current_line_left - previous_line_left - previous_line_width
        previous_line_left = current_line_left
        previous_line_width = row['width']
        if (len(results) and column_separator == 6) and 1250 > current_line_left > 1100:
            result_flag = True
        if line_flag is True:
            result_flag = False
        if len(requirement) and word_num in (1,2,3) and text != 'Note' and 800 > current_line_left > 500 and column_separator < 0:
            requirement_flag = True
        if len(requirement) and line_flag is True and (word_num == 1 or (word_num == 2 and column_separator < 0) or (word_num == 4 and column_separator > 300))and requirement_flag is False and result_flag is False and char_num_text != '' and ref_loc_text != '' and charateristic_designator_text != '':
            each_row.append(char_num_text)
            char_num_text = ''
            each_row.append(ref_loc_text)
            ref_loc_text = ''
            each_row.append(charateristic_designator_text)
            charateristic_designator_text = ''
            each_row.append(' '.join(list(dict.fromkeys(requirement))))
            each_row.append(' '.join(results))
            all_rows.append(each_row)
            each_row = []
            requirement_for_each_line.append(requirement)
            requirement = []
            results = []
        if column_separator < 0 and 100 > current_line_left > 70:
            line_num.append(current_line_number)
            char_num.append(text)
            char_num_text = text
        if 210 > current_line_left >= 190:
            ref_loc.append(text)
            ref_loc_text = text
        if 380 > current_line_left > 370 and len(text) == 5:
            charateristic_designator.append(text)
            Minor_flag = True
            charateristic_designator_text = text
        if Minor_flag == False and charateristic_designator_text == '':
            charateristic_designator.append('Minor')
            charateristic_designator_text = 'Minor'
        if  1090 > current_line_left >= 500:# and 98 > column_separator > 0:
            requirement.append(text)
        if 1250 > current_line_left > 1100:# and column_separator > 100:
            results.append(text)
            resultText = text
            result_flag = False
table = tabulate(all_rows, headers=["5. Char No", "6. Reference", "7. Characteristic", "8. Requirement", "9.Results"])
print(table)


headers=["5. Char No", "6. Reference Location", "7. Characteristic Recoginition", "8. Requirement", "9.Results"]
with open('test_file.csv', 'w', newline = '') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(headers)
    [writer.writerow(r) for r in all_rows]

代码非常复杂,因为如果基本上已经从tesseract中提取了文本,这就是为什么它很复杂,但是我得到的输出是一个巨大的表,所以要求列也包含文本,但是我只在有一个数字条件。正如您在代码末尾看到的那样,我已将输出打印在.csv excel文件中,现在,我需要首先获得在图片中获取范围值的逻辑。

3 个答案:

答案 0 :(得分:1)

df = pd.DataFrame({
    '8. Requirement': ['.685-.695', '.340-.350', '.737-.740', 'foo', '42'],
    '9.Results': [.68, .345, '.739', '.68', 'bar']
})
# or df = pd.read_csv('filename.csv', sep='\t')

df = df.join(df['8. Requirement'].str.extract('(\d*\.?\d+)-(\d*\.?\d+)').rename(columns={0:'min', 1:'max'}))
df['OK'] = pd.to_numeric(df['9.Results'], errors='coerce').between(df['min'].astype(float), df['max'].astype(float))
print(df)

输出:

  8. Requirement 9.Results   min   max     OK
0      .685-.695      0.68  .685  .695  False
1      .340-.350     0.345  .340  .350   True
2      .737-.740      .739  .737  .740   True
3            foo       .68   NaN   NaN  False
4             42       bar   NaN   NaN  False

答案 1 :(得分:0)

另一种解决方案:

data = """
9.results,8. Requirement
.68,.13-.70
.34,.45-.939
.74,.45-.987
.68,.13-.67
.34,.25-.939
.74,.95-.987
   """
df = pd.read_csv(pd.compat.StringIO(data), sep=',')

df[['low', 'high']] = df['8. Requirement'].str.split('-', expand=True)
df['Status'] = df['9.results'].between(df['low'].astype(float), df['high'].astype(float))
df.drop(['low','high'], axis=1,inplace=True)
print(df)

   9.results 8. Requirement  Status
0     0.68     .13-.70    True
1     0.34    .45-.939   False
2     0.74    .45-.987    True
3     0.68     .13-.67   False
4     0.34    .25-.939    True
5     0.74    .95-.987   False

文件的语法:

df = pd.read_csv('test1.csv',sep='\t')#  \t if your delimiter is tab

答案 2 :(得分:0)

这是一种os解决方案,希望其回答您的问题。我将范围列分为两部分,以简化计算。

import pandas as pd
data = [[float(0.685),float(0.695),float(0.68)],[float(0.340),float(0.350),float(0.345)],[float(0.737),float(0.740),float(0.736)]]
df = pd.DataFrame(data,columns=['Requirement1','Requirement2','Results'])
print(df)

   Requirement1  Requirement2  Results
0         0.685         0.695    0.680
1         0.340         0.350    0.345
2         0.737         0.740    0.736

### If between the range
f = df['Results'].between(df['Requirement1'], df['Requirement2'], inclusive=False)
df.insert(3,'Status',f)

   Requirement1  Requirement2  Results  Status
0         0.685         0.695    0.680   False
1         0.340         0.350    0.345    True
2         0.737         0.740    0.736   False

### Changing Bool into custom text 
mask = df.applymap(type) != bool 
d = {True: 'OK', False: 'Not OK'}
df = df.where(mask, df.replace(d))
list_col=['Results']
r = df.drop(list_col,axis=1)
r
r.to_csv(filename,mode = 'w', index=False)

    Requirement1  Requirement2  Status
0         0.685         0.695  Not OK
1         0.340         0.350      OK
2         0.737         0.740  Not OK