我的数据框包含name
,age
,Task1
,Task2
,Task3
。
现在,我需要在Task1
,Task2
,Task3
列中获取满足字符串值的所有行。假设我要检查关键字“草稿”。如果“起草”作为任何这些列值的一部分存在,则必须将整行添加到结果框架中。
我尝试过isin()
,但我是对还是错。我需要提取包含特定关键字的“ N”行。
我试过了
df.columns[df.Task1.str.contains("Drafting")]
,但这比较并给出了单列。
任何人都知道如何使用str.contains或任何其他方法来比较列的字符串值并获取所有满足检查条件的行。
Name Age Task1 Task2 Task3
0 Ann 43 Drafting a Letter sending paking
1 Juh 29 sending paking Letter Drafting
2 Jeo 42 Pasting sending paking
3 Sam 59 sending pasting Letter Drafting
我需要检查关键字“草稿”是否存在于任何列中[该列包含3到4个单词,需要检查此单词/句子中是否存在草稿];结果应该是:
Name Age Task1 Task2 Task3
0 Ann 43 Drafting a Letter sending paking
1 Juh 29 sending paking Letter Drafting
3 Sam 59 sending pasting Letter Drafting
答案 0 :(得分:4)
或者只是(请注意,这将检查整个df而不是特定的列):
df[df.astype(str).apply(lambda x: x.str.contains('Drafting')).any(axis=1)]
#for case insensitive use below
#df[df.astype(str).apply(lambda x: x.str.contains('Drafting',case=False)).any(axis=1)]
Name Age Task1 Task2 Task3
0 Ann 43 Drafting a Letter sending paking
1 Juh 29 sending paking Letter Drafting
3 Sam 59 sending pasting Letter Drafting
答案 1 :(得分:3)
对2万行数据的给定答案进行快速比较-
@Alollz(在评论中)
%timeit df.loc[df.filter(like='Task').applymap(lambda x: 'Drafting' in x).any(1)]
25.2 ms ± 2.09 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
@谢尔盖·布什曼诺夫
%timeit df[df.Task1.str.contains("Drafting") | df.Task2.str.contains("Drafting") | df.Task3.str.contains("Drafting")]
58.7 ms ± 9.25 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
@ anky_91
%timeit df[df.filter(like='Task').apply(lambda x: x.str.contains('Drafting')).any(axis=1)]
88.6 ms ± 12.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit df[df.astype(str).apply(lambda x: x.str.contains('Drafting')).any(axis=1)]
128 ms ± 14.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
@ALollz
%timeit df.loc[df.filter(like='Task').stack().str.split(expand=True).eq('Drafting').any(1).any(level=0)]
290 ms ± 29.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
答案 2 :(得分:1)
您可以尝试:
new_df = df[df.Task1.str.contains("Drafting") | df.Task2.str.contains("Drafting") | df.Task3.str.contains("Drafting")]
这将返回new_df
,其中任何“ Task1,2,3”列中的行均包含“草稿”。
答案 3 :(得分:0)
这可以使用np.where
来实现:
df = pd.DataFrame({
'Name': ['Ann', 'Juh', 'Jeo', 'Sam'],
'Age': [43,29,42,59],
'Task1': ['Drafting a letter', 'Sending', 'Pasting', 'Sending'],
'Task2': ['Sending', 'Paking', 'Sending', 'Pasting'],
'Task3': ['Packing', 'Letter Drafting', 'Paking', 'Letter Drafting']
})
df_new = df.iloc[df.index[np.concatenate(
np.where(df['Task1'].str.contains('Drafting')) +
np.where(df['Task2'].str.contains('Drafting')) +
np.where(df['Task3'].str.contains('Drafting'))).astype(int)
].values.tolist()]
print(df_new)
Name Age Task1 Task2 Task3
0 Ann 43 Drafting a letter Sending Packing
1 Juh 29 Sending Paking Letter Drafting
3 Sam 59 Sending Pasting Letter Drafting
答案 4 :(得分:-2)
您可以尝试这样的事情,
new_df = df[(df['Task1'] == 'Drafting') | (df['Task2'] == 'Drafting') | (df['Task3'] == 'Drafting')]
如果列Task1
或Task2
或Task3
包含“草稿”,则会选择所有行。