基于布尔函数合并熊猫数据框

时间:2020-02-18 15:58:04

标签: python pandas dataframe merge

我正在寻找一种有效的方法来合并一个基于两个数据帧作为输入列并返回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 Lazloo

3 个答案:

答案 0 :(得分:2)

您可以使用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

答案 1 :(得分:1)

您可以使用广播或class Metrics(tf.keras.callbacks.Callback): def __init__(self, valid_data, steps): """ valid_data is a TFRecordDataset with batches of 100 elements per batch, shuffled and repeated infinitely. steps defines the amount of batches per epoch """ super(Metrics, self).__init__() self.valid_data = valid_data self.steps = steps def on_train_begin(self, logs={}): self.cer = [] self.wer = [] def on_epoch_end(self, epoch, logs={}): imgs = [] labels = [] for idx, (img, label) in enumerate(self.valid_data.as_numpy_iterator()): if idx >= self.steps: break imgs.append(img) labels.extend(label) imgs = np.array(imgs) labels = np.array(labels) out = self.model.predict((batch for batch in imgs)) input_length = len(max(out, key=len)) out = np.asarray(out) out_len = np.asarray([input_length for _ in range(len(out))]) decode, log = K.ctc_decode(out, out_len, greedy=True) decode = [[[int(p) for p in x if p != -1] for x in y] for y in decode][0] for (pred, lab) in zip(decode, labels): dist = editdistance.eval(pred, lab) self.cer.append(dist / (max(len(pred), len(lab)))) self.wer.append(not np.array_equal(pred, lab)) print("Mean CER: {}".format(np.mean([self.cer], axis=1)[0])) print("Mean WER: {}".format(np.mean([self.wer], axis=1)[0])) 功能比较所有行。随着长度的增加,您会遇到问题。

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

答案 2 :(得分:0)

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

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')