【问题标题】:Matching if value of a column in a df is one of the values of another column in the same dataframe(going row by row)匹配 df 中列的值是否是同一数据帧中另一列的值之一(逐行)
【发布时间】:2019-05-02 15:00:18
【问题描述】:

df

col1  col2
A      a|x|y
B      a|x|y
C      c|x|z
D      e|j|y

我的目标是创建一个名为“status”的新列,以查看 col1 中的条目是否是 col2 中的条目之一(由管道分隔)。 输出应该是这样的

col1  col2     status
A      a|x|y   True
B      a|x|y   False
C      c|x|z   True
D      e|j|y   False

我的代码:

df["col1"]= df["col1"].str.lower()
df['status']=df['col1'].isin(df['col2']) 

但这将“状态”列中的所有条目都设为 False

请帮帮我,拜托!!!

【问题讨论】:

    标签: python string pandas matching


    【解决方案1】:

    get_dummies

    df.col2.str.get_dummies().mul(pd.get_dummies(df.col1.str.lower())).sum(1).astype(bool)
    
    0     True
    1    False
    2     True
    3    False
    dtype: bool
    

    a = pd.get_dummies(df.col1.str.lower())
    b = df.col2.str.get_dummies()
    status = b.mul(a).sum(1).astype(bool)
    df = df.assign(status=status)
    
    df
    
      col1   col2  status
    0    A  a|x|y    True
    1    B  a|x|y   False
    2    C  c|x|z    True
    3    D  e|j|y   False
    

    get_dummieseinsum

    a = pd.get_dummies(df.col1.str.lower())
    b = df.col2.str.get_dummies()
    a, b = a.align(b, fill_value=0)
    status = np.einsum('ij,ij->i', a, b).astype(bool)
    
    df = df.assign(status=status)
    df
    
      col1   col2  status
    0    A  a|x|y    True
    1    B  a|x|y   False
    2    C  c|x|z    True
    3    D  e|j|y   False
    

    【讨论】:

      【解决方案2】:

      类似于this answer,您可以使用列表推导。假设您的数据是干净的,例如没有空值。

      zipper = zip(df['col1'], df['col2'])
      df['status'] = [i.casefold() in j.casefold().split('|') for i, j in zipper]
      
      print(df)
      
        col1   col2 status
      0    A  a|x|y   True
      1    B  a|x|y  False
      2    C  c|x|z   True
      3    D  e|j|y  False
      

      【讨论】:

      • i.casefold 我无法使用,因为我使用的是 python 2.7,所以我将 i.casefold() 替换为 i.lower() 并提供所需的输出。谢谢! @jpp
      【解决方案3】:

      也许您应该首先将您的数据框转换为更易于使用的格式。

      我建议是这样的:

      >>> df = pd.concat([df['col1'], df['col2'].str.upper().str.split('|', expand=True)], axis=1)                                                                                                             
      >>> df                                                                                                                                                                                                   
        col1  0  1  2
      0    A  A  X  Y
      1    B  A  X  Y
      2    C  C  X  Z
      3    D  E  J  Y
      

      现在你可以这样做了:

      >>> df['status'] = df.apply(lambda s: s.duplicated().any(), axis=1)                                                                                                                                     
      >>> df                                                                                                                                                                                                    
        col1  0  1  2  status
      0    A  A  X  Y    True
      1    B  A  X  Y   False
      2    C  C  X  Z    True
      3    D  E  J  Y   False
      

      此解决方案假定您使用 '|' 分隔的状态指示符是唯一的,即您不能拥有类似 'x|x|x' 的内容。


      如果您不喜欢该建议,请考虑:

      >>> df['status'] = df.apply(lambda row: row[0].lower() in row[1].split('|'), axis=1)                                                                                                                     
      >>> df                                                                                                                                                                                                  
         col1   col2  status
      0    A  a|x|y    True
      1    B  a|x|y   False
      2    C  c|x|z    True
      3    D  e|j|y   False
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-20
        • 2016-09-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多