我想创建一列“ Held?”在我的pandas数据帧中,当同一行的另一个单元格“ HeldDrpTypes”中包含单元格“ DrpType”中的字符时,就会进行标记。
我尝试使用where
和in
,但没有用:
df['Held?'] = where(df['DrpType'] in df['HeldDrpTypes'] == True),'Yes','No')
这就是我要完成的事情:
> print(df)
DrpType HeldDrpTypes Held?
0 A B No
1 B BC Yes
2 C B No
3 B BC Yes
4 A BC No
5 C BC Yes
有什么想法可以解决这个问题吗?
答案 0 :(得分:3)
对于纯熊猫,您可以使用df.apply()
import pandas as pd
df = pd.DataFrame({
'DrpType': ['A', 'B', 'C', 'B', 'A', 'C',],
'HeldDrpTypes':['B', 'BC', 'B', 'BC', 'BC', 'BC']
})
df['Held?'] = df.apply(lambda row: row['DrpType'] in row['HeldDrpTypes'], axis=1)
print(df)
# DrpType HeldDrpTypes Held?
# 0 A B False
# 1 B BC True
# 2 C B False
# 3 B BC True
# 4 A BC False
# 5 C BC True
如果您是Yes
/ No
的拥护者,而不是True
/ False
,则可以使用以下内容,但是我建议您坚持使用二进制{ {1}} / True
可以简化检查真实性的过程,而不必解析字符串。
False
答案 1 :(得分:2)
我对两个答案的时机感到好奇,所以我使用更大的数据框对其进行了测试:
df = pd.concat([df]*100000, ignore_index=True)
print(df.shape)
(600000, 2)
温布斯,答案为list comprehension:
%%timeit
df['Held'] = ['Yes' if x in y else 'No' for x , y in zip(df.DrpType,df.HeldDrpTypes)]
给出以下内容:
304 ms ± 17.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Brian Cohans 使用.apply
%%timeit
df['Held?'] = df.apply(
lambda row: 'Yes' if row['DrpType'] in row['HeldDrpTypes'] else 'No', axis='columns')
给出以下内容:
23.2 s ± 1.23 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
因此,速度差异实际上在+-1000的数量级上,从而有利于list comprehension
答案 2 :(得分:1)
您可以检查
l=['Yes' if x in y else 'No' for x , y in zip(df.DrpType,df.HeldDrpTypes)]
l
Out[196]: ['No', 'Yes', 'No', 'Yes', 'No', 'Yes']
df['Held']=l
或者我们使用numpy
np.core.chararray.find(df.HeldDrpTypes.values.astype(str),df.DrpType.values.astype(str))!=-1
Out[201]: array([False, True, False, True, False, True])