【问题标题】:using isin across multiple columns跨多个列使用 isin
【发布时间】:2019-07-31 12:44:51
【问题描述】:

我正在尝试将 .isin 与 ~ 一起使用,因此我可以根据 2 个数据集中的多列获取唯一行的列表。

所以,我有 2 个包含 9 行的数据集: df1 是底部,df2 是顶部(对不起,我无法让它在下面显示,它显示 1 然后是一行数字)

   Index    Serial  Count   Churn
     1       9         5    0
     2       8         6    0
     3       10        2    1
     4       7         4    2
     5       7         9    2
     6       10        2    2
     7       2         9    1
     8       9         8    3
     9       4         3    5


    Index   Serial  Count   Churn
     1       10      2       1
     2       10      2       1
     3       9       3       0
     4       8       6       0
     5       9       8       0
     6       1       9       1
     7       10      3       1
     8       6       7       1
     9       4       8       0

我想根据多于 1 列从 df1 中获取不在 df2 中的行列表。

例如,如果我基于列 Serial 和 Count 进行搜索,我不会从 df1 返回索引 1 和 2,因为它出现在 df2 中的索引位置 6,与 df1 中的索引位置 4 相同,因为它出现在df2 中的索引位置 2。这同样适用于 df1 中的索引位置 5,因为它位于 df2 中的索引位置 8。

流失列并不重要。

我可以让它工作,但仅基于 1 列,但不能超过 1 列。

df2[~df2.Serial.isin(df1.Serial.values)] 有点像我想要的,但只在 1 列上。我希望它基于 2 个或更多。

  Index Serial  Count   Churn
   3    9          3    0
   6    1          9    1
   7    10         3    1
   8    6          7    1
   9    4          8    0

【问题讨论】:

  • 我有点困惑,您想要 df1 中不存在于 df2 中的行,但您的代码建议相反,df2 中不存在于 df1 中的行。跨度>
  • 对不起,我没注意到。 TBH 无论如何它都可以,因为它只是意味着切换 df1 和 df2。更多的是如何让我正在寻找的查询工作。
  • 是的,我相信您的编辑已经破坏了您的一个数据框,因为它们现在包含相同的值。
  • 是的,很抱歉,它有,但我从未注意到它。我现在已经修好了。

标签: python isinstance


【解决方案1】:

一种解决方案是与指标合并:

df1 = pd.DataFrame([[10, 2, 0], [9, 4, 1], [9, 8, 1], [8, 6, 1], [9, 8, 1], [1, 9, 1], [10, 3, 1], [6, 7, 1], [4, 8, 1]], columns=['Serial', 'Count', 'Churn'])
df2 = pd.DataFrame([[9, 5, 1], [8, 6, 1], [10, 2, 1], [7, 4, 1], [7, 9, 1], [10, 2, 1], [2, 9, 1], [9, 8, 1], [4, 3, 1]], columns=['Serial', 'Count', 'Churn'])
# merge with indicator on
df_temp = df1.merge(df2[['Serial', 'Count']].drop_duplicates(), on=['Serial', 'Count'], how='left', indicator=True)
res = df_temp.loc[df_temp['_merge'] == 'left_only'].drop('_merge', axis=1)

Output        
   Serial  Count  Churn
1       9      4      1
5       1      9      1
6      10      3      1
7       6      7      1
8       4      8      1

【讨论】:

  • 谢谢,那行得通。我不能给你“有用的答案”,因为我没有足够的代表。
  • 完成,谢谢。第一次在这里发帖,所以我什至不知道这是一个选择。再次感谢。
  • 没问题,很高兴我能帮上忙!
【解决方案2】:

我有类似的问题要解决,我找到了处理它的最简单方法,方法是创建一个临时列,该列由合并的标识符列组成,并在这个新创建的临时列值上使用 isin

实现此目的的简单函数如下

from functools import reduce

get_temp_col = lambda df, cols: reduce(lambda x, y: x + df[y].astype('str'), cols, "")

def subset_on_x_columns(df1, df2, cols):
    """
    Subsets the input dataframe `df1` based on the missing unique values of input columns
    `cols` of dataframe `df2`.

    :param df1: Pandas dataframe to be subsetted
    :param df2: Pandas dataframe which missing values are going to be 
                used to subset `df1` by
    :param cols: List of column names
    """
    df1_temp_col = get_temp_col(df1, cols)
    df2_temp_col = get_temp_col(df2, cols)

    return df1[~df1_temp_col.isin(df2_temp_col.unique())]

因此,对于您的情况,所需要的只是执行:

result_df = subset_on_x_columns(df1, df2, ['Serial', 'Count'])

其中有想要的行:

   Index  Serial  Count  Churn
      3       9      3      0
      6       1      9      1
      7      10      3      1
      8       6      7      1
      9       4      8      0

这个解决方案的好处是它可以自然地在使用的列数上进行扩展,即只需在输入参数列表cols 中指定哪些列用作标识符。

【讨论】:

    猜你喜欢
    • 2020-08-17
    • 2015-02-10
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多