【问题标题】:Countif pandas python for multiple columns with wildcardCountif pandas python用于带有通配符的多列
【发布时间】:2020-08-23 01:25:07
【问题描述】:

我在 Excel 中有一个要复制的数据集。

我的python代码如下:

data_frames = [df_mainstore, df_store_A, df_store_B]
df_merged = reduce(lambda  left,right: pd.merge(left,right,on=["Id_number"], how='outer'), data_frames)
print(df_merged)

由于我合并了几个数据框(列号和名称可能不同),因此写出在此 example 中完成的所有列也会很乏味:

isY = lambda x:int(x=='Y')
countEmail= lambda row: isY(row['Store Contact A']) + isY(row['Store B Contact'])
df['Contact Email'] = df.apply(countEmail,axis=1)

我也很纠结这种表达方式:isY = lambda x:int(x=='@')

如何以与 Excel 中类似的方式添加“联系人有电子邮件”列?

【问题讨论】:

    标签: python pandas countif


    【解决方案1】:

    您可以使用filter 选择其中包含联系人的列,然后使用str.contains 和正确的pattern for email address,最后您希望每行都使用any

    #data sample
    df_merged = pd.DataFrame({'id': [0,1,2,3], 
                              'Store A': list('abcd'),
                              'Store Contact A':['aa@bb.cc', '', 'e', 'f'], 
                              'Store B': list('ghij'),
                              'Store B Contact':['kk@ll.m', '', 'nn@ooo.pp', '']})
    
    # define the pattern as in the link
    pat = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"
    # create the column as wanted
    df_merged['Contact has Email'] = df_merged.filter(like='Contact')\
                                              .apply(lambda x: x.str.contains(pat))\
                                              .any(1)
    
    print (df_merged)
       id Store A Store Contact A Store B Store B Contact  Contact has Email
    0   0       a        aa@bb.cc       g         kk@ll.m               True
    1   1       b                       h                              False
    2   2       c               e       i       nn@ooo.pp               True
    3   3       d               f       j                              False
    

    【讨论】:

    • 非常感谢!!!!!!!!!非常感谢。为了使其 100% 正常工作,我需要调整所有“联系人”一词都以大写字母 C 开头。此外,我使用了正则表达式:[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+ 使其更具动态性。真的很高兴所有的帮助和意见:)!
    • @Wizhi 如果你不总是有资本C,你也可以使用filter(regex='Contact|contact'),但我敢肯定还有更灵活的方式。很高兴它有帮助:)
    • @Wizhi 你可以试试df_merged['Store Contact A'].str.extract(pat),其中 pat 略有不同pat = r"([a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+)" 请注意你所做的正则表达式周围的(),但如果你想要一个可行的解决方案,也许一个新问题会更好
    • 感谢您的回复!!我会尝试使用您的建议。如果我不解决它,我会问一个新问题。再次感谢!! :)!
    • @Wizhi 不确定你想要的结果,但是这个df_merged.filter(like='Contact').apply(lambda x: x.str.extract(pat)[0]).agg(list, axis=1) 给出了每行所有电子邮件的列表
    【解决方案2】:

    您可以使用pandas.Series.str.contains

    df_merged['Contact has Email'] = df_merged['Store Contact A'].str.contains('@', na=False)|df_merged['Store B Contact'].str.contains('@', na=False)
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-22
      • 2022-01-17
      • 2014-09-08
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      • 2019-09-04
      • 2020-01-19
      相关资源
      最近更新 更多