Pandas Dataframe,如何计算每列的值每次超过或低于两个数字的阈值

iq3niunx  于 2023-06-28  发布在  其他
关注(0)|答案(2)|浏览(155)

我有一个这样的 Dataframe :

account1    account2    account3    account4
0   4.730500    18.899000   5.926950    3.548100
1   3.922000    11.609333   4.405667    5.333333
2   5.172667    12.932667   4.772167    5.500000
3   4.429833    10.694667   4.859500    8.36100
4   5.149167    13.496667   8.451045    5.166667
5   2.598000    10.655500   5.952333    4.833333
6   5.805167    15.418000   5.296167    4.450000
7   4.168833    9.624833    5.436333    4.403333
8   4.452750    14.699750   4.757250    4.896000

我有三个由阈值4和7定义的组,每个点都可以是其中的一部分。我想计数每一次一列中的行移动到一个阈值并进入一个新的组(低于4,高于4,高于7或低于7)。
例如,帐户1更改组:
| 指数|分组变化|
| - -----|- -----|
| 0| 0|
| 一个|一个|
| 2|一个|
| 三个|0|
| 4| 0|
| 5个|一个|
| 六|一个|
| 七个|0|
| 八|0|
因此,account 1更改组4次
我希望输出是一个 Dataframe ,如:

account1          account2       account3        account4
0   4                 0              2               3

我尝试将点的值更改为不同的组名称,如:

df[df < 4]= 0
df[(df >= 4) & (df <=7)] = 1
df[df > 7]= 2

然后我有一个这样的 Dataframe :

account1    account2    account3    account4
0   1.0         2.0         1.0         0.0
1   0.0         2.0         1.0         1.0
2   1.0         2.0         1.0         1.0
3   1.0         2.0         1.0         2.0
4   1.0         2.0         2.0         1.0
5   0.0         2.0         1.0         1.0
6   1.0         2.0         1.0         1.0
7   1.0         2.0         1.0         1.0
8   1.0         2.0         1.0         1.0

然后执行一些apply函数来计算不匹配的连续行值的出现次数,如:df.apply(lambda x : sum(x.iloc[-1:] != x.shift(-1).iloc[1:]))
这显然不起作用,我相信这是一个优雅的解决方案,可以跳过将值转换为1,2,3。
感谢您的评分

arknldoa

arknldoa1#

你快到了!。使用pd.cut简化条件,使用diff检查组是否已更改。仅计算差值不等于0的行(新组):

def group_changes(sr):
    bins = [-np.inf, 4, 7, np.inf]
    groups = pd.cut(sr, bins=bins, labels=False)
    return groups.diff().fillna(0).ne(0).sum()

out = df.apply(group_changes)

输出:

>>> out
account1    4
account2    0
account3    2
account4    3
dtype: int64

account1的详细信息:

bins = [-np.inf, 4, 7, np.inf]
pd.concat({'cut': (out := pd.cut(df['account1'], bins=bins, labels=False)),
           'diff': (out := out.diff().fillna(0)),
           'fillna': (out := out.ne(0))},
          axis=1)

# Output
   cut  diff  fillna
0    1   0.0   False
1    0  -1.0    True
2    1   1.0    True
3    1   0.0   False
4    1   0.0   False
5    0  -1.0    True
6    1   1.0    True
7    1   0.0   False
8    1   0.0   False
8i9zcol2

8i9zcol22#

这也应该起作用:

df.clip(4,7).ne(df).diff().ne(0).cumsum().sub(1).max().to_frame().T

输出:

account1  account2  account3  account4
0         4         0         2         3

相关问题