【问题标题】:Create new column with value from matches from two other columns in pandas使用来自 pandas 中其他两列的匹配项创建新列
【发布时间】:2019-04-02 16:44:02
【问题描述】:

下面是我拥有的pandas data frame 的一个子集

           index             name_matches dist_matches
38  PO1000000345                  M-00346      M-00346
39  PO1000000352                               M-00804
40  PO1000000354                  M-00196      M-00196
41  PO1000000355                  M-00514      M-00514
42  PO1000000382          M-00353,M-00354      M-00354
43  PO1000000411                                      
44  PO1000000451                                      
45  PO1000000512                               M-00680
46  PO1000000530                  M-00089             
47  PO1000000531                  M-00087      M-00087
48  PO1000000553  M-00917,M-00920,M-00922      M-00920

我正在尝试获取一个新列 (comb_matches),它会提取 name_matchesdist_matches 列中的匹配值。有时,用逗号分隔的列中会有一个或多个值。我希望得到的输出示例如下所示。

           index             name_matches dist_matches  comb_matches
38  PO1000000345                  M-00346      M-00346       M-00346
39  PO1000000352                               M-00804
40  PO1000000354                  M-00196      M-00196       M-00196
41  PO1000000355                  M-00514      M-00514       M-00514
42  PO1000000382          M-00353,M-00354      M-00354       M-00354
43  PO1000000411                                      
44  PO1000000451                                      
45  PO1000000512                               M-00680
46  PO1000000530                  M-00089             
47  PO1000000531                  M-00087      M-00087       M-00087
48  PO1000000553  M-00917,M-00920,M-00922      M-00920       M-00920

有什么简单的方法可以得到上面的吗?

【问题讨论】:

标签: python pandas


【解决方案1】:

没有简单的方法。 Pandas 不是为此类任务而设计的,它不可矢量化。您最好的选择可能是列表理解:

s1 = df['dist_matches'].astype(str)
s2 = df['name_matches'].astype(str).str.split(',')
mask = [i in j for i, j in zip(s1, s2)]

df['comb_match'] = np.where(mask, df['dist_matches'], np.nan)

性能基准测试

为了证明 Pandas str 方法并不是真正矢量化的事实:

# Python 3.6.5, Pandas 0.23.0

def wen(df):
    Bool = df.name_matches.str.split(',',expand=True).isin(df.dist_matches).any(1)    
    df['comb_match'] = np.where(Bool, df.dist_matches, '')
    return df

def jpp(df):
    s1 = df['dist_matches'].astype(str)
    s2 = df['name_matches'].astype(str).str.split(',')
    mask = [i in j for i, j in zip(s1, s2)]
    df['comb_match'] = np.where(mask, df['dist_matches'], np.nan)
    return df

df = pd.concat([df]*1000, ignore_index=True)

assert jpp(df).equals(wen(df))

%timeit jpp(df)  # 12.2 ms
%timeit wen(df)  # 32.7 ms

【讨论】:

    【解决方案2】:

    isin 之前使用 str.split 。然后我们将布尔值实现为np.where

    Bool=df.name_matches.str.split(',',expand=True).isin(df.dist_matches).any(1)    
    df['comb_match']=np.where(Bool,df.dist_matches,'')
    df
    Out[520]: 
               index             name_matches dist_matches comb_match
    38  PO1000000345                  M-00346      M-00346    M-00346
    39  PO1000000352                               M-00804           
    40  PO1000000354                  M-00196      M-00196    M-00196
    41  PO1000000355                  M-00514      M-00514    M-00514
    42  PO1000000382          M-00353,M-00354      M-00354    M-00354
    43  PO1000000411                                                 
    44  PO1000000451                                                 
    45  PO1000000512                               M-00680           
    46  PO1000000530                  M-00089                        
    47  PO1000000531                  M-00087      M-00087    M-00087
    48  PO1000000553  M-00917,M-00920,M-00922      M-00920    M-00920
    

    【讨论】:

    • 嘿文,介意解释.any 方法吗?非常酷,我从你身上学到了很多。
    • @Datanovice any 如果任何值为 True ,则返回 True ,只有在所有值为 False 时才返回 False 。这里 i 表示 axis=1 ,逐行检查。
    • 感谢@Wen,这很好用。不幸的是,我刚刚遇到另一种情况,在dist_matches 中也有由列分隔的值。这段代码需要稍微修改一下吗?
    • @Funkeh-Monkeh 是的,那么你需要查看设置交点
    猜你喜欢
    • 2019-07-15
    • 2020-06-15
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 2020-06-02
    相关资源
    最近更新 更多