【问题标题】:return a match more than 2 numbers that match side by side返回并排匹配的超过 2 个数字的匹配项
【发布时间】:2023-01-01 05:26:11
【问题描述】:

我有一个名为 df1 的数据框,其中 1 行有 6 个数字,另一个名为 df2 的数据框有超过 500 行,有 ID 和 6 个数字。在 df1 中,我想查找 6 个数字并在 df2 中找到它们,并且只返回匹配的数字 并排匹配 2 个以上的数字。它可以是 df1 中的任意 6 个数字,只要它同时匹配 2 个以上的数字即可。我在下面创建了一个小例子,

import pandas as pd 

df1 = pd.DataFrame([[2,4,6,8,9,10]], columns = 
['Num1','Num2','Num3','Num4','Num5','Num6'])


df2    = pd.DataFrame([[100,1,2,4,5,6,8],
                       [87,1,6,20,22,23,34],
                       [99,1,12,13,34,45,46],
                       [64,1,10,14,29,32,33],
                       [55,1,22,13,23,33,35],
                       [66,1,6,7,8,9,10],
                       [77,1,2,3,5,6,8],
                       [811,1,2,5,6,8,10], 
                       [118,1,7,8,22,44,56],
                       [117,1,66,44,47,87,91],
                       [299,2,4,7,20,21,22],
                       [187,3,6,10,12,25,39],
                       [199,4,12,24,34,56,57],
                       [264,3,7,8,9,10,33],
                       [50,6,8,10,23,33,35],
                       [212,4,6,12,18,19,20],
                       [45,3,7,23,35,56,88],
                       [801,1,2,4,6,28,39], 
                       [258,2,3,4,9,10,41],
                       [220,5,6,10,27,57,81]],
                       columns = ['Id', 'Num1','Num2','Num3','Num4','Num5','Num6'])

我希望我的结果像下面这样。

result = pd.DataFrame([[66,1,6,7,8,9,10],
                        [811,1,2,5,6,8,10], 
                        [264,3,7,8,9,10,33],
                        [50,6,8,10,23,33,35],
                        [801,1,2,4,6,28,39], 
                        [258,2,3,4,9,10,41],
                        [220,4,6,10,27,57,81]],
                        columns = ['Id', 'Num1','Num2','Num3','Num4','Num5','Num6']) 

为什么这些数字。因为数字并排匹配超过 2 个数字

66, 8,9,10
811, 6,8,10         
264, 8,9,10         
50, 6,8,10
801, 2,4,6
258, 4,9,10
220, 4,6,10    

我也在下面尝试了这段代码,但它只返回一个超过 2 个但不是并排的匹配项。希望我说得有道理。

vals_to_find = set(df1.iloc[0])
mask = df2.loc[:, "Num1":].apply(lambda x: 
len(vals_to_find.intersection(x)) > 2, axis=1)
print(df2[mask])        

【问题讨论】:

  • 根据 df1 6, 8, 10 不是并排的。
  • 我知道,但它可以是 df1 中的任意 3 个数字。它可以是 4、8、10 等。我试图在 df2 中并排找到超过 3 个数字的匹配项。你明白我在说什么吗
  • @Chris 我已经发布了一个答案。如果有问题,请告诉我。如果它解决了您的问题,您可以接受并点赞。

标签: python pandas list dataframe jupyter-notebook


【解决方案1】:

我认为这正是你想要的:

import numpy as np
import pandas as pd

# Save the numbers in df1 in a list as their order does not matter
key = df1.T[0].to_list()

# Check to see how many of those numbers are in df2
temp = df2[df2.isin(key)]

我写了一个自定义函数,它获取每一行并检查是否有超过 2 个并排的连续数字。它使用 jezrael 的答案,您可以找到 here

def side_counter(Num1, Num2, Num3, Num4, Num5, Num6):
    row = pd.Series([Num1, Num2, Num3, Num4, Num5, Num6])
    row = row.astype(float)
    m = row.isnull()
    s = m.cumsum()
    x = s.map(s[~m].value_counts()).ge(3) & ~m
    has_side = x.sum() # if the row has more than two side by side return more than 0
    if has_side == 0:
        return False
    else:
        return True

# Apply the method and save the result in a new column as boolean
df2["has_2sidebyside"] = temp.apply(lambda x: side_counter(x['Num1'], x["Num2"], x["Num3"], x["Num4"], x["Num5"], x["Num6"]), axis=1)

# Mask the dataframe based on the boolean column
result = df2[df2["has_2sidebyside"]==True].drop("has_2sidebyside", axis=1)
result

Id  Num1 Num2 Num3 Num4 Num5 Num6
5   66  1   6   7   8   9   10
7   811 1   2   5   6   8   10
13  264 3   7   8   9   10  33
14  50  6   8   10  23  33  35
17  801 1   2   4   6   28  39
18  258 2   3   4   9   10  41

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 2019-02-17
    • 2017-06-13
    • 1970-01-01
    • 2020-08-07
    • 2017-05-20
    • 2013-04-18
    相关资源
    最近更新 更多