我有一个pandas dataframe,其中一个列包含字符串,字符串可以是"a“、"b”和"c“的任意组合。例如,单元格可以是"a“或"a,b,c”或"b,a,c“等等。我希望能够检查单元格是否按任意顺序包含"a“、"b”和"c“,然后将其替换为数字或将数字添加到其旁边的新列中。我知道使用str.contains可以做到这一点,如下所示,但我希望避免写下所有的组合。
df["cat"]=df["cat"].str.contains('a,b,c|a,c,b|c,b,a|b,a,c|c,a,b|b,c,a').astype(int)
有谁知道我怎么做的吗?
发布于 2019-04-04 02:00:59
您可以使用itertools.permutations
创建您的正则表达式模式。
import itertools
cats = ['a', 'b', 'c']
pat = '|'.join([','.join(x) for x in itertools.permutations(cats)])
# print(pat)
# 'a,b,c|a,c,b|b,a,c|b,c,a|c,a,b|c,b,a'
df["cat"] = df["cat"].str.contains(pat).astype(int)
示例
df = pd.DataFrame({'cat': {0: 'a,b,c',1: 'a,c,b',2: 'c,b,a',3: 'b,a,c',4: 'c,a,b',5: 'b,c,a',6: 'd,e,f',7: 'a,a,a',8: 'a',9:'b',10: 'c'}})
print(df)
cat
0 a,b,c
1 a,c,b
2 c,b,a
3 b,a,c
4 c,a,b
5 b,c,a
6 d,e,f
7 a,a,a
8 a
9 b
10 c
cats = ['a', 'b', 'c']
pat = '|'.join([','.join(x) for x in itertools.permutations(cats)])
df["match"] = df["cat"].str.contains(pat).astype(int)
print(df)
cat match
0 a,b,c 1
1 a,c,b 1
2 c,b,a 1
3 b,a,c 1
4 c,a,b 1
5 b,c,a 1
6 d,e,f 0
7 a,a,a 0
8 a 0
9 b 0
10 c 0
发布于 2019-04-04 04:42:38
正则表达式编辑:添加正则表达式负前视选项
选项1:使用负先行
In [887]: df
Out[887]:
cat
0 a,b,c
1 a,c,b
2 c,b,a
3 b,a,c
4 c,a,b
5 b,c,a
6 a,a,a
7 b,b,b
8 c,c,c
9 a,b
10 ab,a
11 b
12 ab,c
13 a,b,a
14 a,b,b
15 c,b,a
16 a,a,b
17 a,bc
18 a, b,c
19 a,bb,c
In [888]: ignore_st = r'(?:([abc]),(?!.*\1)){2}[abc]'
In [896]: df['ignore'] = df.cat.str.contains(ignore_st).astype(int)
In [897]: df
Out[897]:
cat ignore
0 a,b,c 1
1 a,c,b 1
2 c,b,a 1
3 b,a,c 1
4 c,a,b 1
5 b,c,a 1
6 a,a,a 0
7 b,b,b 0
8 c,c,c 0
9 a,b 0
10 ab,a 0
11 b 0
12 ab,c 0
13 a,b,a 0
14 a,b,b 0
15 c,b,a 1
16 a,a,b 0
17 a,bc 0
18 a, b,c 0
19 a,bb,c 0
选项2:仅当每个单元格包含'a,b,c‘的精确组合时才有效
可以将每个单元格与数组['a', 'b', 'c']
进行比较,而不是使用str.contains
正则表达式
In [800]: df
Out[800]:
cat
0 a,b,c
1 a,c,b
2 c,b,a
3 b,a,c
4 c,a,b
5 b,c,a
6 a,a,a
7 b,b,b
8 c,c,c
9 a,b
10 a,c
11 b
12 c
在每个单元格上,按','
拆分以列出、排序和比较每个单元格与['a', 'b', 'c']
In [810]: df['ignore'] = df.cat.str.split(',').map(sorted).apply(lambda x: x == ['a', 'b', 'c']).astype(int)
In [811]: df
Out[811]:
cat ignore
0 a,b,c 1
1 a,c,b 1
2 c,b,a 1
3 b,a,c 1
4 c,a,b 1
5 b,c,a 1
6 a,a,a 0
7 b,b,b 0
8 c,c,c 0
9 a,b 0
10 a,c 0
11 b 0
12 c 0
https://stackoverflow.com/questions/55501365
复制相似问题