df
col1 col2
A a|x|y
B a|x|y
C c|x|z
D e|j|y
我的目标是创建一个名为“状态”的新列,以查看col1中的条目是否为col2中的条目之一(由管道分隔)。 输出应该是这样
col1 col2 status
A a|x|y True
B a|x|y False
C c|x|z True
D e|j|y False
我的代码:
df["col1"]= df["col1"].str.lower()
df['status']=df['col1'].isin(df['col2'])
但这会将“状态”列中的所有条目都设为False
请帮助我!!!
答案 0 :(得分:3)
get_dummies
df.col2.str.get_dummies().mul(pd.get_dummies(df.col1.str.lower())).sum(1).astype(bool)
0 True
1 False
2 True
3 False
dtype: bool
a = pd.get_dummies(df.col1.str.lower())
b = df.col2.str.get_dummies()
status = b.mul(a).sum(1).astype(bool)
df = df.assign(status=status)
df
col1 col2 status
0 A a|x|y True
1 B a|x|y False
2 C c|x|z True
3 D e|j|y False
get_dummies
和einsum
a = pd.get_dummies(df.col1.str.lower())
b = df.col2.str.get_dummies()
a, b = a.align(b, fill_value=0)
status = np.einsum('ij,ij->i', a, b).astype(bool)
df = df.assign(status=status)
df
col1 col2 status
0 A a|x|y True
1 B a|x|y False
2 C c|x|z True
3 D e|j|y False
答案 1 :(得分:2)
类似于this answer,您可以使用列表推导。假设您的数据是干净的,例如没有空值。
zipper = zip(df['col1'], df['col2'])
df['status'] = [i.casefold() in j.casefold().split('|') for i, j in zipper]
print(df)
col1 col2 status
0 A a|x|y True
1 B a|x|y False
2 C c|x|z True
3 D e|j|y False
答案 2 :(得分:2)
也许您应该将数据框转换为更易于使用的格式。
我建议这样:
>>> df = pd.concat([df['col1'], df['col2'].str.upper().str.split('|', expand=True)], axis=1)
>>> df
col1 0 1 2
0 A A X Y
1 B A X Y
2 C C X Z
3 D E J Y
现在您可以这样做:
>>> df['status'] = df.apply(lambda s: s.duplicated().any(), axis=1)
>>> df
col1 0 1 2 status
0 A A X Y True
1 B A X Y False
2 C C X Z True
3 D E J Y False
此解决方案假定您用'|'
分隔的状态指示器是唯一的,即您不能使用类似'x|x|x'
的东西。
如果您不喜欢该建议,请考虑:
>>> df['status'] = df.apply(lambda row: row[0].lower() in row[1].split('|'), axis=1)
>>> df
col1 col2 status
0 A a|x|y True
1 B a|x|y False
2 C c|x|z True
3 D e|j|y False