我有一个包含多列的数据框。其中一列(在示例中以 B 表示)可用作触发器,即 我必须在第一个值大于0.5之后删除所有行。但是,我必须保留第一个数字。
上面给出了一个例子。删除所有在0.59之后的行(这是遵循大于0.5的条件的第一行)。
initial_df = pd.DataFrame([[1,0.4], [5,0.43], [4,0.59], [11,0.41], [9,0.61]], columns = ['A', 'B'])
下面的蓝色框表示触发器,红色框表示必须删除的值。 最后,我们将获得:
是否有可能以一种有效的方式在熊猫中做到这一点(而不是使用for循环)?
答案 0 :(得分:2)
因此,如果您的索引与iloc
相同,则此方法有效:
first_occurence = initial_df[initial_df.B>0.5].index[0]
initial_df.iloc[:first_occurence+1]
编辑:这是一个更通用的解决方案
first_occurence = initial_df.index.get_loc(initial_df[initial_df.B>0.5].iloc[0].name)
final_df = initial_df.iloc[:first_occurence+1]
答案 1 :(得分:2)
您可以将np.where
与布尔索引一起使用,以提取与条件匹配的第一个值的 positioning 索引。然后将其输入iloc
:
idx = np.where(df['B'].gt(0.5))[0][0]
res = df.iloc[:idx+1]
print(res)
A B
0 1 0.40
1 5 0.43
2 4 0.59
对于可能很早就满足条件的非常大的数据帧,更理想的方法是将next
与生成器表达式一起使用来计算idx
:
idx = next((idx for idx, val in enumerate(df['B']) if val > 0.5), len(df.index))
要获得更好的性能,请参见Efficiently return the index of the first value satisfying condition in array。
答案 2 :(得分:1)
我找到了一种类似于jpp所示的解决方案:
indices = initial_df.index
trigger = initial_df[initial_df.B > 0.5].index[0]
initial_df[initial_df.index.isin(indices[indices<=trigger])]
由于实际数据帧具有多个索引,所以这是我找到的唯一解决方案。
答案 3 :(得分:0)
我假设您要删除“ B”列值小于0.5的所有行。
尝试一下:
initial_df = pd.DataFrame([[1, 0.4], [5, 0.43], [4, 0.59], [11, 0.41], [9, 0.61]], columns=['A', 'B'])
final_df = initial_df[initial_df['B'] >= 0.5]
结果数据帧final_df为:
A B
2 4 0.59
4 9 0.61