例如我创建了这个数据框:
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 函数的东西来检查前一行的值是否相同,但我不确定如何添加计数功能来为其提供我想要的参数。
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
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
实现此目的的另一种方法:
pd.Series.value_counts
获取 df['Cycle']
中所有唯一值的计数。pd.Series.between
获得一系列布尔值。'good'|'bad'
变成 replace
,然后将其传递到应用于 pd.Series.map
列的
Cycle
。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
这是一种使用
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