基于以下資料框:
import json
import numpy as np
import pandas as pd
test_list = ['purple', 'red', 'yellow']
df = pd.DataFrame({'numbers': [1, 2, 3], 'colors': [['red','blue'], ['white'], ['blue','yellow']]})
df['colors_new'] = df.colors.map(tuple)
我正在嘗試生成一個新列,如果 test_list 中至少有一個元素在每一行中,那么我將該行標記為 true
df['found'] = any((True for x in test_list if x in df['colors_new']))
df

在上面的例子中,第 0 行和第 2 行應該為真,因為紅色在第 0 行,黃色在第 2 行
這將是最有效和正確的方法,因為我目前得到了錯誤的結果
我認為我能得到正確回應的最接近的是
df['found'] = ['red' in x for x in df['colors_new']]
但是當我有多個專案時使用它不起作用(test_list = ['purple', 'red', 'yellow'])

uj5u.com熱心網友回復:
isdisjoint如果性能很重要,請使用集合:
s = set(test_list)
df['colors_new'] = ~df.colors.map(s.isdisjoint)
或者:
s = set(test_list)
df['colors_new'] = df['colors'].map(s.intersection).astype(bool)
print (df)
numbers colors colors_new
0 1 [red, blue] True
1 2 [white] False
2 3 [blue, yellow] True
測驗資料中的性能,真實的最佳測驗,因為取決于 DataFrame 的長度、測驗串列的長度、匹配值的數量:
df['colors_new'] = df.colors.map(tuple)
#3k rows
df = pd.concat([df] * 1000, ignore_index=True)
test_list = ['purple', 'red', 'yellow']
s = set(test_list)
In [46]: %timeit df['colors_new'] = ~df.colors.map(s.isdisjoint)
707 μs ± 20.7 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [47]: %timeit df['colors_new'] = df['colors'].map(s.intersection).astype(bool)
1.38 ms ± 153 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [50]: %timeit df['found'] = df['colors_new'].apply(lambda x: len(s.intersection(x))>0)
1.68 ms ± 42.7 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [51]: %timeit df['found'] = df['colors_new'].explode().isin(test_list).groupby(level=0).max()
4.66 ms ± 166 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [52]: %timeit df['found'] = df['colors_new'].apply(lambda x: bool(max([1 if y in test_list else 0 for y in x])))
2.91 ms ± 118 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [54]: %timeit df["colors_map"] = df[['colors','colors_new']].apply(lambda x:any([x2 in test_list for x1 in x for x2 in x1]), axis=1)
26.1 ms ± 1.22 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
uj5u.com熱心網友回復:
使用爆炸
df['found'] = df['colors_new'].explode().isin(test_list).groupby(level=0).max()
輸出:
numbers colors colors_new found
0 1 [red, blue] (red, blue) True
1 2 [white] (white,) False
2 3 [blue, yellow] (blue, yellow) True
使用 python 集
您可以使用 set and set.intersection,如果交集不為空,則有共同的值。
集合操作比經典回圈快。
test_list = set(test_list)
df['found'] = df['colors_new'].apply(lambda x: len(test_list.intersection(x))>0)
輸出:
numbers colors colors_new found
0 1 [red, blue] (red, blue) True
1 2 [white] (white,) False
2 3 [blue, yellow] (blue, yellow) True
注意。作為獎勵,您可以使用相同的方法來獲取找到的元素
df['found elements'] = df['colors_new'].apply(test_list.intersection)
輸出:
numbers colors colors_new found found elements
0 1 [red, blue] (red, blue) True {red}
1 2 [white] (white,) False {}
2 3 [blue, yellow] (blue, yellow) True {yellow}
uj5u.com熱心網友回復:
您可以使用該lambda功能來獲得您想要的:
import json
import numpy as np
import pandas as pd
test_list = ['purple', 'red', 'yellow']
df = pd.DataFrame({'numbers': [1, 2, 3], 'colors': [['red','blue'], ['white'], ['blue','yellow']]})
df['colors_new'] = df.colors.map(tuple)
df['found'] = df['colors_new'].apply(lambda x: bool(max([1 if y in test_list else 0 for y in x])))
uj5u.com熱心網友回復:
您也可以使用串列推導式:
df["colors_map"] = df[['colors','colors_new']].apply(lambda x:any([x2 in test_list for x1 in x for x2 in x1]), axis=1)
如果您有很多colors要檢查的列(不僅僅是 2 個):
df["colors_map"] = df[[x for x in df.columns if "colors" in x]].apply(lambda x:any([x2 in test_list for x1 in x for x2 in x1]), axis=1)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/360291.html
