我的数据帧是:
import pandas as pd
df = pd.DataFrame(
{
'a': [-3, -1, -2, -5, 10, -3, -13, -3, -2, 1, 2, -100],
}
)
预期输出:
a
0 -3
1 -1
2 -2
3 -5
逻辑:
我想返回最大的负数条纹。如果有多个连续最大,我想返回第一个连续。在
df
中有两条大小为4的负条纹,因此返回第一个。
这是我的尝试,但每当我在代码中使用
idxmax()
时,我想仔细检查,因为有时它会变得棘手一些场景。
import numpy as np
df['sign'] = np.sign(df.a)
df['sign_streak'] = df.sign.ne(df.sign.shift(1)).cumsum()
m = df.sign.eq(-1)
group_sizes = df.groupby('sign_streak').size()
largest_group = group_sizes.idxmax()
largest_group_df = df[df['sign_streak'] == largest_group]
的方法和对
idxmax()
的谨慎是合理的。 但是,可以通过利用 Pandas 的一些内置功能来简化逻辑并避免使用
idxmax()
的潜在陷阱:
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': [-3, -1, -2, -5, 10, -3, -13, -3, -2, 1, 2, -100]})
# 计算符号和符号变化
df['sign'] = np.sign(df.a)
df['sign_change'] = (df.sign != df.sign.shift()).cumsum()
# 为负数序列创建一个组
df['negative_group'] = (df.sign == -1).cumsum()
# 获取每个组的大小并找到最大组的索引
group_sizes = df[df.sign == -1].groupby('negative_group').size()
max_group_index = group_sizes.index[0] if len(group_sizes) > 0 else None
# 提取最大负序列
result = df[df.negative_group == max_group_index]
print(result)
解释:
- 标识符号变化: 与的方法类似,此代码会标识数字符号的变化。
-
负数组:
它会创建一个新的组变量
negative_group
,该变量仅在遇到负数时递增。 这将所有负序列分组在一起。 -
查找最大组:
它会计算每个
negative_group
中的大小,找到最大组,并提取其索引。 -
提取结果:
最后,它根据确定的
negative_group
索引提取属于最大负序列的行。
这段代码没有依赖
idxmax()
,而是直接使用组大小信息来找到最大负序列。 这使得逻辑更加健壮和易于理解。