Python Pandas:计算后续值的数量并在满足条件时分配名称

问题描述 投票:0回答:4

例如我创建了这个数据框:

import pandas as pd

df = pd.DataFrame({'Cycle': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
                             2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]})


#Maybe something like this: df['Cycle Type'] = df['Cycle'].rolling(2).apply(lambda x: len(set(x)) != len(x),raw= True).replace({0 : False, 1: True})

我想计算值的数量,然后为其分配一种循环类型。如果循环少于 12 行或多于 100 行,则将其标记为坏,否则将其标记为好。我正在考虑使用类似 lambda 函数的东西来检查前一行的值是否相同,但我不确定如何添加计数功能来为其提供我想要的参数。

python pandas dataframe count
4个回答
3
投票

首先计算每组中的行数,其中

pandas.DataFrame.groupby
pandas.DataFrame.transform
pandas.DataFrame.count

df["cycle_quality"] = df.groupby("Cycle")["Cycle"].transform("count")

然后使用

pandas.DataFrame.apply
:

将质量函数应用于它

• 如果行数小于 12 且大于 100,则将

cycle_quality
定义为
bad

• 否则,

cycle_quality
应该是
good

df["cycle_quality"] = df.apply(lambda x: "bad" if x["cycle_quality"] < 12 or x["cycle_quality"] > 100 else "good", axis=1)

[Out]:
    Cycle cycle_quality
0       0          good
1       0          good
2       0          good
3       0          good
4       0          good
..    ...           ...
71      5           bad
72      5           bad
73      5           bad
74      5           bad
75      5           bad

2
投票

使用

groupby
transform
获取每个周期的大小,并使用
between
查看每个周期的大小是否落在 13、100(包括两者)之间,并将 True 标记为良好和假一样糟糕。因为根据要求,任何小于 12 且大于 100 的尺寸都是不好的,而 [13, 100] 之间的其他尺寸都是好的。

df['Cycle_Type'] = df.groupby('Cycle')['Cycle'].transform('size').between(13, 100,
        inclusive='both').replace({True: 'good', False: 'bad'})

输出:

    Cycle Cycle_Type
0       0        bad
1       0        bad
2       0        bad
3       0        bad
4       0        bad
..    ...        ...
71      5        bad
72      5        bad
73      5        bad
74      5        bad
75      5        bad

编辑:

您可以根据需要更改您想要好或坏的时间间隔。 如果您的要求是少于 12 个应该标记为良好,则在间隔中包含 12,例如:

df['Cycle_Type'] = df.groupby('Cycle')['Cycle'].transform('size').between(12, 100,
            inclusive='both').replace({True: 'good', False: 'bad'})

那么你的输出是:

    Cycle Cycle_Type
0       0       good
1       0       good
2       0       good
3       0       good
4       0       good
..    ...        ...
71      5        bad
72      5        bad
73      5        bad
74      5        bad
75      5        bad

2
投票

实现此目的的另一种方法:

import pandas as pd

df = pd.DataFrame({'Cycle': [0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5]})

vc = df.Cycle.value_counts()

df['Cycle_Type'] = df['Cycle'].map(
    vc.between(12,100,inclusive='both').replace({True: 'good', False: 'bad'}))

# printing output per value
print(df.groupby('Cycle', as_index=False).first())

   Cycle Cycle_Type
0      0       good
1      1        bad
2      2       good
3      3       good
4      4       good
5      5        bad

2
投票

这是一种使用

pd.cut()
的方法。如果需要应用比好和坏更多的类别,这可能很有用。

(df['Cycle']
.map(
    pd.cut(df['Cycle'].value_counts(),
    bins = [0,12,100,np.inf],
    right = False,
    labels = ['bad','good','bad'],
    ordered=False)))

s = df['Cycle'].diff().ne(0).cumsum()
np.where(s.groupby(s).transform('count').between(12,100),'good','bad')

或使用

pd.IntervalIndex()

idx = pd.IntervalIndex.from_breaks([0,12,100,np.inf],closed = 'left')
pd.Series(['bad','good','bad'],index = idx).reindex(df.groupby(df['Cycle'].diff().ne(0).cumsum()).transform('size')).reset_index(drop=True)

输出:

0     good
1     good
2     good
3     good
4     good
      ... 
71     bad
72     bad
73     bad
74     bad
75     bad
© www.soinside.com 2019 - 2024. All rights reserved.