【问题标题】:How do I check if a dataframe column contains any values of a dictionary and if true copy the dictionary values in a new column of the DF?如何检查数据框列是否包含字典的任何值以及是否将字典值复制到 DF 的新列中?
【发布时间】:2022-06-26 05:09:40
【问题描述】:

我正在努力完成三件事。首先,我想检查dictionary 中的任何值是否包含在dataframe 列的任何值中。其次,对于 dataframe 列中包含 dictionary 值的每个值,我想在正在检查的列旁边的新列中输入该 dictionary 值。第三,我想在新列中输入dictionary 值的关联键。我想我在确定包含函数是否为真时被困在if condition 上。请注意,这只是一个示例,真正的字典将有数百个键/值,并且字典有大约一百万行。此外,尽管很少见,dataframe 列可能包含字典中的多个值。如果有更好的方法来做这一切,我愿意接受。

字典 - dict1:

{'Delay one': ['this delay happens', 'this delay may happen'],
 'Delay two': ['this delay happens a lot', 'this delay happens almost'],
 'Other': ['this delay occurs']}

数据框 - df2:

col1            col2                             col3
0     1   1/1/2021 2:07         this delay happens often
1     2  1/5/2021 19:21    this delay happens a lot here
2     3   1/1/2021 2:51   this delay happens almost alot
3     4   1/1/2021 5:24  this delay happens almost never
4     5   1/1/2021 5:24                              nan
5     9  1/1/2021 10:55                             null

期望的结果:

col1    col2    col3    contain_value   associated_key
0   1   1/1/2021 2:07   this delay happens often.   this delay happens  Delay one
1   2   1/5/2021 19:21  this delay happens a lot here.  this delay happens a lot    Delay two
2   3   1/1/2021 2:51   this delay happens almost alot. this delay happens almost   Delay two
3   4   1/1/2021 5:24   this delay happens almost never.    this delay happens almost   Delay two
4   5   1/1/2021 5:24   NaN NaN NaN
5   9   1/1/2021 10:55  Null    NaN NaN

代码:

# create dictionary
dict1 = df.groupby('col2')['col3'].agg(list).to_dict()

# Series created from dataframe so that contain function can be used; not sure if entire dataframe # can be used with contained function and if that would be better
series = df2['col3']

# function - if value in series contains any dict1 values put dict1 value in new column

def contain(note):
    for key, value in dict1.items():
        for v in range(len(value)):
            contain = series[(series.str.contains(value[v]))]
            if contain:
                return v
    
# apply function to get dictionary values that are contained in DF column
df2['contain_value'] = df2['col3'].apply(lambda x: contain(x))

# Not sure how to incorporate in the contain function on how to get key
df2['associated_key'] = df2['col3'].apply(lambda x: contain(x))

错误:

ValueError                                Traceback (most recent call last)
C:\Users\HECTOR~1.HER\AppData\Local\Temp/ipykernel_25036/3873876505.py in <module>
     25 
     26 # xact_notes_match_comments
---> 27 df2['contain_value'] = df2['col3'].apply(lambda x: contain(x))
     28 
     29 

C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\series.py in apply(self, func, convert_dtype, args, **kwargs)
   4355         dtype: float64
   4356         """
-> 4357         return SeriesApply(self, func, convert_dtype, args, kwargs).apply()
   4358 
   4359     def _reduce(

C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\apply.py in apply(self)
   1041             return self.apply_str()
   1042 
-> 1043         return self.apply_standard()
   1044 
   1045     def agg(self):

C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\apply.py in apply_standard(self)
   1096                 # List[Union[Callable[..., Any], str]]]]]"; expected
   1097                 # "Callable[[Any], Any]"
-> 1098                 mapped = lib.map_infer(
   1099                     values,
   1100                     f,  # type: ignore[arg-type]

C:\ProgramData\Anaconda3\lib\site-packages\pandas\_libs\lib.pyx in pandas._libs.lib.map_infer()

C:\Users\HECTOR~1.HER\AppData\Local\Temp/ipykernel_25036/3873876505.py in <lambda>(x)
     25 
     26 # xact_notes_match_comments
---> 27 df2['contain_value'] = df2['col3'].apply(lambda x: contain(x))
     28 
     29 

C:\Users\HECTOR~1.HER\AppData\Local\Temp/ipykernel_25036/3873876505.py in contain(note)
     20         for v in range(len(value)):
     21             contain = series[(series.str.contains(value[v]))]
---> 22             if contain:
     23                 return contain
     24 

C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\generic.py in __nonzero__(self)
   1535     @final
   1536     def __nonzero__(self):
-> 1537         raise ValueError(
   1538             f"The truth value of a {type(self).__name__} is ambiguous. "
   1539             "Use a.empty, a.bool(), a.item(), a.any() or a.all()."

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

【问题讨论】:

  • 这是 .loc 和 str.contains 的工作。它也将比应用更快。例如:for k,v in dict1.items(): df.loc[(df[col3].notnull()) &amp; (df['col3'].str.contains('|'.join(v))), 'col4'] = k。我不确定我的代码是否已格式化!文档很好地解释了这一点,让我知道我是否可以提供更多帮助,只是不确定我是否可以给出通常需要的答案深度。 @hector.h2913
  • 反转字典的映射有多可行?
  • @IrisD 谢谢。首先,我看不到col4=k 部分的用途。你可以解释吗?我删除了这些,只是返回了df2.loc[(df2['col3'].notnull()) &amp; (df2['col3'].str.contains('|'.join(values)))]。那里不是 100%,但我正在努力。其次,我认为 contains 函数应该从一个较大的字符串返回一个子字符串,就像在你建议的代码中一样,我调整了 this delay happens almost never 在 col3 中返回但 'this delay happens a lot''this delay happens almost' 不返回。
  • @IrisD 第三如何在我的df2 中获得一个新列,其中包含来自dict1 的包含/匹配值?
  • @enke 如果我理解正确,我认为这是不可行的,因为每个键都有多个值。

标签: python dataframe dictionary contains


【解决方案1】:

您的contain 函数应如下所示::

def contain(note):
    for key, value in dict1.items():
        for v in range(len(value)):
            contain = series[(series.str.contains(value[v]))]
            if not contain.empty:
                return v

【讨论】:

    猜你喜欢
    • 2017-09-12
    • 2020-05-09
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 2021-05-18
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多