Python、Pandas:检查列列表值中的每个元素是否存在于其他数据框中
Python, Pandas: check each element in list values of column to exist in other dataframe
我的数据框列在列表中有值,如果它们在其他数据框中,我想添加带有列表中过滤值的新列。
df:
df = pd.DataFrame({'a':[1,2,5,7,9],'b':[[10,1,'xxx'],[],[1,2,3],[5],[25,27]]})
**a**|**b**
:-----:|:-----:
1|[10, 1, 'xxx']
2|[]
5|[1, 2, 3]
7|[5]
9|[25, 27]
df2:
df2 = pd.DataFrame({'d':[324,21,4353,345,4535,23],'e':[5,1,23,25,25,'xxx']})
我需要在 df
中添加带有过滤列 b
的新列,以便它包含仅包含 df2
列 e
中的元素的列表。
结果:
**a**|**b**|**c**
:-----:|:-----:|:-----:
1|[10, 1, 'xxx']|[1,'xxx']
2|[]|[]
5|[1, 2, 3]|[1]
7|[5]|[5]
速度很重要,因为有大量的记录。
我现在做了什么:
- 创建了一组可能的值
l = list(df2['e'].unique())
- 尝试将
df.assign
与综合列表一起使用,但效果不佳且速度太慢。
df.assign(mapped=[[x for x in row if x in l] for row in df.b])
感谢任何帮助。
UPD
在列表和 df2 中并不总是整数值,有时是字符串。
您可以尝试转换为 str
然后 series.str.findall
l = map(str,df2['e'].unique())
df['c'] = df['b'].astype(str).str.findall('|'.join([fr"\b{i}\b" for i in l]))
或更短的 findall 模式礼貌 @Shubham:
l = map(str,df2['e'].unique())
df['c'] = df['b'].astype(str).str.findall(fr"\b({'|'.join(l)})\b")
print(df)
a b c
0 1 [10, 1, 100] [1]
1 2 [] []
2 5 [1, 2, 3] [1]
3 7 [5] [5]
4 9 [25, 27] [25]
您可以按如下方式使用np.intersect1d()
:
l = df2['e'].unique() # unique() already returns ndarray, no need to use list()
df['c'] = df['b'].map(lambda x: np.intersect1d(x, l))
print(df)
a b c
0 1 [10, 1, 100] [1]
1 2 [] []
2 5 [1, 2, 3] [1]
3 7 [5] [5]
4 9 [25, 27] [25]
编辑
根据OP对混合类型数据的编辑,我们只需要修改提取df2
列e
的唯一值的方式即可。无需更改创建列 c
.
的主要代码
l = list(map(str, df2['e'].unique())) # only change this
df['c'] = df['b'].map(lambda x: np.intersect1d(x, l))
print(df)
a b c
0 1 [10, 1, xxx] [1, xxx]
1 2 [] []
2 5 [1, 2, 3] [1]
3 7 [5] [5]
4 9 [25, 27] [25]
今天,我处理了一个类似的问题,我需要获取包含我们要查找的值的行,但数据框的列值是列表格式。
这是我想出的解决方案。
fetched_rows = df.loc [ df['column_name'].map( lambda x : True if check_element in x else False) == True ]
在哪里
column_name ---> 我们需要查看的列名称
check_element ---> 我们用来检查它是否存在的值。
我的数据框列在列表中有值,如果它们在其他数据框中,我想添加带有列表中过滤值的新列。
df:
df = pd.DataFrame({'a':[1,2,5,7,9],'b':[[10,1,'xxx'],[],[1,2,3],[5],[25,27]]})
**a**|**b**
:-----:|:-----:
1|[10, 1, 'xxx']
2|[]
5|[1, 2, 3]
7|[5]
9|[25, 27]
df2:
df2 = pd.DataFrame({'d':[324,21,4353,345,4535,23],'e':[5,1,23,25,25,'xxx']})
我需要在 df
中添加带有过滤列 b
的新列,以便它包含仅包含 df2
列 e
中的元素的列表。
结果:
**a**|**b**|**c**
:-----:|:-----:|:-----:
1|[10, 1, 'xxx']|[1,'xxx']
2|[]|[]
5|[1, 2, 3]|[1]
7|[5]|[5]
速度很重要,因为有大量的记录。
我现在做了什么:
- 创建了一组可能的值
l = list(df2['e'].unique())
- 尝试将
df.assign
与综合列表一起使用,但效果不佳且速度太慢。
df.assign(mapped=[[x for x in row if x in l] for row in df.b])
感谢任何帮助。
UPD
在列表和 df2 中并不总是整数值,有时是字符串。
您可以尝试转换为 str
然后 series.str.findall
l = map(str,df2['e'].unique())
df['c'] = df['b'].astype(str).str.findall('|'.join([fr"\b{i}\b" for i in l]))
或更短的 findall 模式礼貌 @Shubham:
l = map(str,df2['e'].unique())
df['c'] = df['b'].astype(str).str.findall(fr"\b({'|'.join(l)})\b")
print(df)
a b c
0 1 [10, 1, 100] [1]
1 2 [] []
2 5 [1, 2, 3] [1]
3 7 [5] [5]
4 9 [25, 27] [25]
您可以按如下方式使用np.intersect1d()
:
l = df2['e'].unique() # unique() already returns ndarray, no need to use list()
df['c'] = df['b'].map(lambda x: np.intersect1d(x, l))
print(df)
a b c
0 1 [10, 1, 100] [1]
1 2 [] []
2 5 [1, 2, 3] [1]
3 7 [5] [5]
4 9 [25, 27] [25]
编辑
根据OP对混合类型数据的编辑,我们只需要修改提取df2
列e
的唯一值的方式即可。无需更改创建列 c
.
l = list(map(str, df2['e'].unique())) # only change this
df['c'] = df['b'].map(lambda x: np.intersect1d(x, l))
print(df)
a b c
0 1 [10, 1, xxx] [1, xxx]
1 2 [] []
2 5 [1, 2, 3] [1]
3 7 [5] [5]
4 9 [25, 27] [25]
今天,我处理了一个类似的问题,我需要获取包含我们要查找的值的行,但数据框的列值是列表格式。
这是我想出的解决方案。
fetched_rows = df.loc [ df['column_name'].map( lambda x : True if check_element in x else False) == True ]
在哪里 column_name ---> 我们需要查看的列名称
check_element ---> 我们用来检查它是否存在的值。