我有熊猫数据框。我想从col1中选择值,该值应在col2中具有所有3个值。
col2_values_should start_with = [P1.adv, P2.cmp, P3.part ]
另外,由于您可以在col2中看到值的后面部分,因此是虚拟的。因此我需要使用与SQL的LIKE运算符类似的选项来检查col2值。
所以上表的答案是:
因为与B和C不同,“ A”具有所有必需的三个值。
所以基本上我想检查col1中的哪个值在col2中具有所有3个必需值。这些col2值应以上述某些字母开头。
编辑:
样本数据
ID col1 col2
1 A P1.adv abcd
2 A P2.cmp mkmfwk
3 A P3.part lpwf
4 B P1.adv abcd
5 B P2.cmp mkmfwk
6 C P1.addv abcd
7 C P1.adv abcd
答案 0 :(得分:2)
这是一种方法:
l = ('P1.adv', 'P2.cmp', 'P3.part' )
m1 = df.groupby('col1').apply(lambda x: x.col2.str.startswith(l, na=False)).reset_index()
m2 = df[m1.col2].groupby('col1').col2.nunique() > 2
df[df.col1.isin(m2[m2].index.values)]
ID col1 col2
0 1 A P1.adv abcd
1 2 A P2.cmp kmasd
2 3 A P3.part lpw
说明
您可以先使用str.startswith
检查df
中的哪些行包含以列表中的一项开头的col2
。
print(m1)
col1 level_1 col2
0 A 0 True
1 A 1 True
2 A 2 True
3 B 3 True
4 B 4 True
5 C 5 True
6 C 6 True
使用GroupBy.nunique()
分组col1
并检查唯一项的数量是否大于2(意味着列表中的每个元素至少存在一次)之后:
print(m2)
col1
A True
B False
C False
Name: col2, dtype: bool
最后使用df
在原始m2
上使用布尔索引:
result = df[df.col1.isin(m2[m2].index.values)]
print(result)
ID col1 col2
0 1 A P1.adv abcd
1 2 A P2.cmp kmasd
2 3 A P3.part lpw
答案 1 :(得分:1)
将extract
与正则表达式一起使用,其中^
用于字符串的匹配开始,|
用于OR
,然后将groupby
与transform
并比较{ {1}} s,也正在比较是否像set
这样的组长:
list
另一种解决方案是按startswith
过滤,然后与size
进行计数计数,按nunique
获得唯一值的数量,并按列表长度进行比较,最后按{{3}进行过滤}},并用L = ["P1.adv", "P2.cmp", "P3.part"]
pat = '|'.join(r"^{}".format(x) for x in L)
s = df['col2'].str.extract('('+ pat + ')', expand=False)
df = df[s.groupby(df['col1']).transform(lambda x: set(x) == set(L) and len(x) == len(L))]
print (df)
ID col1 col2
0 1 A P1.adv abcd
1 2 A P2.cmp mkmfwk
2 3 A P3.part 1pwf
检查两个值是否均为all
:
True
答案 2 :(得分:0)
我建议使用正则表达式并计算A
的出现次数等于[模式匹配
import pandas as pd
df = pd.DataFrame({'a':[1,2,1,1,5,5],'b':["abc.more","abcde.kef","abc.mop","lop.e","lop.e","get.le"]})
con = df.b.str.match('^(abc.m|lop.e)')
df['c'] = con
df['sum_c'] = df.groupby('a')['c'].transform('sum')
df['count_a'] = df.groupby('a')['a'].transform('count')
dff = df[df['count_a']==df['sum_c']]
dff
答案 3 :(得分:0)
在数据框中创建一个临时列,以检查col2中是否存在任何目标前缀。然后将它们按col1求和。然后检查总和是否等于3
ans = (df.assign(temp = df.col2.str.startswith(tuple(col2_values_should_start_with)))\
.groupby('col1')[['temp']].sum() == 3).reset_index()
最后,找到具有3个起始字符串的col1的值
df[df['col1'].isin(list(ans[ans.temp == True].col1))]
输出:
ID col1 col2
1 A P1.advabcd
2 A P2.cmpmkmfwk
3 A P3.partlpwf