【问题标题】:Merge Pandas Dataframe based on boolean function基于布尔函数合并 Pandas Dataframe
【发布时间】:2020-02-18 15:58:04
【问题描述】:

我正在寻找一种基于函数的有效方法来合并两个 pandas 数据帧,该函数将两个数据帧的输入列作为输入列并返回 True 或 False。例如。假设我有以下“表格”:

import pandas as pd

df_1 = pd.DataFrame(data=[1, 2, 3])
df_2 = pd.DataFrame(data=[4, 5, 6])


def validation(a, b):
    return ((a + b) % 2) == 0

我想在第一列之和为偶数的每一行加入 df1 和 df2。结果表将是

       1 5
df_3 = 2 4
       2 6
       3 5

请将其视为一般问题,而不是仅返回 df_3 的任务。该解决方案应接受任何验证列组合并返回 True 或 False 的函数。

THX 拉兹鲁

【问题讨论】:

    标签: python pandas dataframe merge


    【解决方案1】:

    您可以使用 merge 进行奇偶校验:

    (df_1.assign(parity=df_1[0]%2)
         .merge(df_2.assign(parity=df_2[0]%2), on='dummy')
         .drop('parity', axis=1)
    )
    

    输出:

       0_x  0_y
    0    1    5
    1    3    5
    2    2    4
    3    2    6
    

    【讨论】:

      【解决方案2】:

      您可以使用广播或outer 函数来比较所有行。随着长度变大,您会遇到问题。

      import pandas as pd
      import numpy as np
      
      def validation(a, b):
          """a,b : np.array"""
          arr = np.add.outer(a, b)     # How to combine rows
          i,j = np.where(arr % 2 == 0) # Condition
      
          return pd.DataFrame(np.stack([a[i], b[j]], axis=1))
      
      validation(df_1[0].to_numpy(), df_2[0].to_numpy())
      
         0  1
      0  1  5
      1  2  4
      2  2  6
      3  3  5
      

      在这种特殊情况下,您可能会利用这样一个事实,即偶数在添加到偶数时保持奇偶性,而奇数在添加到奇数时会改变奇偶性,因此定义该列并在其上合并。

      df_1['parity'] = df_1[0]%2
      df_2['parity'] = df_2[0]%2
      
      df_3 = df_1.merge(df_2, on='parity')
      
         0_x  parity  0_y
      0    1       1    5
      1    3       1    5
      2    2       0    4
      3    2       0    6
      

      【讨论】:

        【解决方案3】:

        这是一个基本的解决方案,但如果您正在处理大型数据帧,则效率不是很高

        df_1.index *= 0
        df_2.index *= 0
        df = df_1.join(df_2, lsuffix='_2')
        df = df[df.sum(axis=1) % 2 == 0]
        

        编辑, 这是一个更好的解决方案

        df_1.index = df_1.iloc[:,0] % 2
        df_2.index = df_2.iloc[:,0] % 2
        df = df_1.join(df_2, lsuffix='_2')
        

        【讨论】:

          猜你喜欢
          • 2016-11-22
          • 1970-01-01
          • 1970-01-01
          • 2018-02-05
          • 2014-02-17
          • 1970-01-01
          • 1970-01-01
          • 2018-02-17
          • 1970-01-01
          相关资源
          最近更新 更多