簡體   English   中英

根據另一列是否包含列表中的名稱,在 Pandas 中設置一列

[英]Set a column in Pandas based on if another column contains a name from a list

我一直在努力解決這個問題,所以我想是時候問了。

我有一個名字列表:

names = ["john", "sally", "tom"]

我有一個 df ,其中一列是action action有很多不同的東西,例如:

  • “和湯姆一起散步”
  • “帶莎莉去商店”
  • ...

我想創建一個名為partner的新列,並將其設置為正在使用的action 我已經設置了列,並為一些日志填充了它,但不是全部。

我試過了:

for name in names:
    df['partner'] =  np.where(df.action.str.contains(name), name, df['partner'] )

但我得到這個錯誤:

TypeError:第一個參數必須是字符串或編譯模式

我會以正確的方式解決這個問題嗎? 有一個更好的方法嗎? 任何幫助,將不勝感激。

編輯:要制作我的 df 樣本,您可以使用:

names = ["john", "sally", "tom"]
d = {'name': ['mark','rick','mark','jon', 'lenny'], 'action': ['Went for a walk with tom', 'Took sally to the store', 'Went for a walk with john', 'Went racing with tom and lost', 'Took john to the store'],
    'partner': ['tom', '', 'john', '', 'john']}
df = pd.DataFrame(data=d)
df

列表“名稱”包含字符串中所有可能的名稱,因此我認為最簡單的方法是找到字符串中的名稱並將其設置為合作伙伴列。

這是我得到的完整錯誤:


TypeError                                 Traceback (most recent call last)
<ipython-input-68-ed79b0ff06a7> in <module>()
     11 
     12 for partner in partners:
---> 13     EscrowLogs.loc[EscrowLogs.action.str.contains(partner), 'partner'] = partner
     14 
     15 

~\Anaconda3\lib\site-packages\pandas\core\strings.py in contains(self, pat, case, flags, na, regex)
   2415     def contains(self, pat, case=True, flags=0, na=np.nan, regex=True):
   2416         result = str_contains(self._data, pat, case=case, flags=flags, na=na,
-> 2417                               regex=regex)
   2418         return self._wrap_result(result)
   2419 

~\Anaconda3\lib\site-packages\pandas\core\strings.py in str_contains(arr, pat, case, flags, na, regex)
    385             flags |= re.IGNORECASE
    386 
--> 387         regex = re.compile(pat, flags=flags)
    388 
    389         if regex.groups > 0:

~\Anaconda3\lib\re.py in compile(pattern, flags)
    232 def compile(pattern, flags=0):
    233     "Compile a regular expression pattern, returning a Pattern object."
--> 234     return _compile(pattern, flags)
    235 
    236 def purge():

~\Anaconda3\lib\re.py in _compile(pattern, flags)
    283         return pattern
    284     if not sre_compile.isstring(pattern):
--> 285         raise TypeError("first argument must be string or compiled pattern")
    286     p = sre_compile.compile(pattern, flags)
    287     if not (flags & DEBUG):

TypeError: first argument must be string or compiled pattern

我需要一個可驗證的數據樣本來確定,但是使用 boolean 索引應該可以工作:

for name in names:
     df.loc[df.action.str.contains(name), 'partner'] = name

跟進我的評論,您可以編寫 function 來遍歷 dataframe 的行並捕獲產生錯誤/異常的值。

例如,如果無法解析操作字段,您可以使用返回 null 值的 function 值:

names = ["john", "sally", "tom"]

def get_partner(p, a):
    # if row already contains partner value, leave as is
    if p:
        return p
    # otherwise, extract partner name from the action column
    else:
        try:
            for name in names:
                if name in a:
                    return name
        # for any problematic action strings, return null value
        # (can be replaced with some other string that you can later check)
        except:
            return None

您也可以使用不需要循環名稱的 function。 它將每個句子拆分為單詞列表,並刪除名稱列表中未找到的所有單詞,只留下名稱值。 如果有多個名稱,則使用逗號分隔符將它們分開。

names = ["john", "sally", "tom"]

def get_partner(p, a):
    # if row already contains partner value, leave as is
    if p:
        return p
    # otherwise, extract partner name(s) from the action column
    else:
        try:
            return ",".join([i for i in a.split() if i in names])
        # for any problematic action strings, return null value
        # (can be replaced with some other string that you can later check)
        except:
            return None

然后,您將使用.apply()在 dataframe 上運行 function:

df['partner'] = df.apply(lambda x: get_partner(x['partner'], x['action']), axis=1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM