Python 3.x 如何根据其他列的差异连接文本列?

Python 3.x 如何根据其他列的差异连接文本列?,python-3.x,pandas,dataframe,Python 3.x,Pandas,Dataframe,我有以下数据帧 top bottom fontname size x0 x1 text 0 62.890 73.890 HNGMRP+HelveticaNeueLTStd-Bd 11.000 321.730 520.115 RISK MANAGEMENT AND INTERNAL 1 76.893 87.893 HNGMRP+

我有以下数据帧

       top   bottom                      fontname    size       x0       x1                           text
0   62.890   73.890  HNGMRP+HelveticaNeueLTStd-Bd  11.000  321.730  520.115  RISK MANAGEMENT AND INTERNAL 
1   76.893   87.893  HNGMRP+HelveticaNeueLTStd-Bd  11.000  321.730  376.334                        CONTROL
2  146.897  157.897  HNGMRP+HelveticaNeueLTStd-Bd  11.000   76.535  203.662              COMPANY SECRETARY
3  272.913  283.913  HNGMRP+HelveticaNeueLTStd-Bd  11.000   76.535  222.593          INDEPENDENT AUDITORS 
4  286.916  297.916  HNGMRP+HelveticaNeueLTStd-Bd  11.000   76.535  167.164                   REMUNERATION
我想

  • 行[i]。text
    行[i+1]的文本连接起来。text
    if
    abs(行[i]。底部行[i+1]。顶部行[i]。大小
  • 合并的\u text
    替换为
    行[i]。text
  • 替换
    第[i]行。底部
    第[i+1]行。底部
  • 放弃
    行[i+1]
  • 例如:

    • 第0行
      文本
      风险管理和内部
    • 第1行
      文本
      控件
    • 第0行
      第1行
      大小相同:11
    • abs(第[0]行)。底部第[1]行。顶部)
      为3.003
    因为
    3.003<11

    • 所需的
      行[0]。文本
      风险管理和内部控制
    • 所需的
      行[0]。底部
      87.893
    • 行[1]
      已从数据帧中删除
    为清楚起见,预期结果如下:

           top   bottom                      fontname    size       x0       x1                           text
    0   62.890   87.893  HNGMRP+HelveticaNeueLTStd-Bd  11.000  321.730  520.115  RISK MANAGEMENT AND INTERNAL CONTROL
    1  146.897  157.897  HNGMRP+HelveticaNeueLTStd-Bd  11.000   76.535  203.662  COMPANY SECRETARY
    2  272.913  297.916  HNGMRP+HelveticaNeueLTStd-Bd  11.000   76.535  222.593  INDEPENDENT AUDITORS REMUNERATION
    
    这就是我所尝试的:

    def df_section_text(self) -> pd.DataFrame:
        df_title_text = self.df_title_text
        df_next_title_text = self.df_title_text.shift(-1).dropna()
        df_section_text = pd.DataFrame()
        
        for next_title, title in zip(df_next_title_text.itertuples(index=False),  df_title_text.itertuples(index=False)):
            diff_btw_titles = abs(title.bottom - next_title.top)
            
            if diff_btw_titles < title.size:
                title = pd.DataFrame([title]).to_dict()
                title['bottom'][0] = next_title.bottom
                title['text'][0] += next_title.text
                title = pd.DataFrame.from_dict(title)
            
            df_section_text = df_section_text.append([title])
        
        df_section_text = df_section_text.drop_duplicates(subset=['bottom']).reset_index()
        return df_section_text
    
    def df_section_text(self)->pd.DataFrame:
    df_title_text=self.df_title_text
    df_next_title_text=self.df_title_text.shift(-1).dropna()
    df_section_text=pd.DataFrame()
    对于下一个标题,zip中的标题(df_next_title_text.itertuples(index=False),df_title_text.itertuples(index=False)):
    diff_btw_titles=abs(title.bottom-next_title.top)
    如果不同标题
    其中
    self.df\u title\u text
    是上述问题数据框


    当行数增加时,速度会变慢。是否有另一种更快、更优雅的方法可以产生预期的结果?谢谢。

    让我们尝试使用
    shift
    cumcount
    获取子组,然后我们只需要根据该键使用
    agg进行
    groupby

    s = (df['bottom'].shift()-df['top']).abs().gt(df['size']).cumsum()
    
    out = df.groupby(s).agg({'top':'first',
                             'bottom':'last',
                             'fontname':'first',
                             'size':'first',
                             'x0':'first',
                             'x1':'first',
                             'text':' '.join})
    
    
    out
    Out[20]: 
           top   bottom  ...       x1                               text
    0   62.890   87.893  ...  520.115  RISKMANAGEMENTANDINTERNAL CONTROL
    1  146.897  157.897  ...  203.662                   COMPANYSECRETARY
    2  272.913  297.916  ...  222.593   INDEPENDENTAUDITORS REMUNERATION
    [3 rows x 7 columns]
    

    这是一个极好的答案。此外,因为
    top
    bottom
    的类型是
    Decimal
    s=((df['bottom'].shift()-df['top']).abs()>df['size'])。cumsum()
    将避免错误
    Decimal.invalidooperation:[]