Python 如何基于另一列的两个连续值在pandas中的新列中添加标签?
我有一个数据帧,Python 如何基于另一列的两个连续值在pandas中的新列中添加标签?,python,pandas,Python,Pandas,我有一个数据帧,df,有一列,扩展名 extension列中的值呈周期性增加和减少,如下所示: extension 0.000 0.050 0.100 0.150 0.130 0.080 0.020 0.050 0.075 extension lablel 0.000 1 0.050 1 0.100 1 0.150 1 0.130 1 0.080 1 0.020 1 0.050 2 0.075 2 我试
df
,有一列,扩展名
extension
列中的值呈周期性增加和减少,如下所示:
extension
0.000
0.050
0.100
0.150
0.130
0.080
0.020
0.050
0.075
extension lablel
0.000 1
0.050 1
0.100 1
0.150 1
0.130 1
0.080 1
0.020 1
0.050 2
0.075 2
我试图给每一个增加和减少的周期贴上标签,如下所示:
extension
0.000
0.050
0.100
0.150
0.130
0.080
0.020
0.050
0.075
extension lablel
0.000 1
0.050 1
0.100 1
0.150 1
0.130 1
0.080 1
0.020 1
0.050 2
0.075 2
我有点卡住了,希望能在这里得到一些指导。让我们重现一下您的数据:
df['lablel']=df.extension.diff()#Find the difference between consecutive ros in the column extension
df['lablel']=(df.lablel.ge(0)&df.lablel.shift(1).le(0)|df.lablel.ge(0)&df.lablel.shift(-1).le(0)).cumsum()+1#Find zero crossing from the consecutive differences, cummulatively sum and add 1 to the outcome
extension lablel
0 0.000 1
1 0.050 1
2 0.100 1
3 0.150 2
4 0.130 2
5 0.080 2
6 0.020 2
7 0.050 3
8 0.075 3
a = [0.000,0.050,0.100,0.150,0.130,0.080,0.020,0.050,0.075]
df = pd.DataFrame(a, columns=["extension"])
简单的答案是:
0 NaN
1 0.050
2 0.050
3 0.050
4 -0.020
5 -0.050
6 -0.060
7 0.030
8 0.025
array([1, 1, 1, 1, 0, 0, 0, 1, 1])
0 NaN
1 0.0
2 0.0
3 0.0
4 -1.0
5 0.0
6 0.0
7 1.0
8 0.0
0 NaN
1 0.0
2 0.0
3 0.0
4 1.0
5 1.0
6 1.0
7 2.0
8 2.0
diff
创建每个单元格与上一个单元格之间的差异。因此,它无法为第一个元素计算它
输出:
0 NaN
1 0.050
2 0.050
3 0.050
4 -0.020
5 -0.050
6 -0.060
7 0.030
8 0.025
array([1, 1, 1, 1, 0, 0, 0, 1, 1])
0 NaN
1 0.0
2 0.0
3 0.0
4 -1.0
5 0.0
6 0.0
7 1.0
8 0.0
0 NaN
1 0.0
2 0.0
3 0.0
4 1.0
5 1.0
6 1.0
7 2.0
8 2.0
现在,让我们使用numpy中的where
对结果进行二值化,以检测正/负差异的变化:
np.where(df["extension"].diff() < 0, 0, 1)
这告诉我们与上一个的差异是负(-->0)还是正(-->1)
然后,您只想知道正/负趋势何时变化。因此,我们再次合并了diff
功能。在此之前,我们必须将numpy数组转换回一个pd.Series
:
pd.Series(np.where(df["extension"].diff() < 0, 0, 1)).diff()
最终,您对趋势的变化方向不感兴趣,只对趋势的变化感兴趣,因此我们使用abs
功能删除此信息。然后使用cumsum
函数将结果相加,以便每次更改时它都会增加:
pd.Series(np.where(df["extension"].diff() < 0, 0, 1)).diff().abs().cumsum()
最后,添加两个以1而不是0为基准的标签,并替换第一个为NaN的项目:
+1位于代码后面,且df.at[0,“label”]=1
你看:
extension label
0 0.000 1.0
1 0.050 1.0
2 0.100 1.0
3 0.150 1.0
4 0.130 2.0
5 0.080 2.0
6 0.020 2.0
7 0.050 3.0
8 0.075 3.0
编辑:回答评论中编辑的问题非常感谢您的回答!!你帮了我很多。但还有一个简单的问题。如果我想在什么时候标记一个完整的周期呢?我的意思是,不要在扩展列中标记每个递增和递减,而是将一组递增和递减标记为一个循环。例如,扩展从0开始,上升到0.1,然后返回到0.05。怎么能把所有这些都标为一个周期呢?我不确定我能不能跟你说。编辑您的问题并包括示例输出。完成后请告诉我,我们将帮助尝试df['label']=df.extension.diff()
,然后df['label']=(df.label.ge(0)和df.label.shift(1.le(0)).cumsum()+1
会有帮助,很高兴能进一步帮助。非常感谢您的详细解释。我只是稍微修改一下这个问题,请你快速看一下好吗?从数学上来说,你的第一个要求更简单,因为这在技术上是数学图表的拐点。然而,按照目前的方法,我们可以说,从技术上讲,你只需要增加标签频率的一半。这可以用一个简单的/2
来完成,然后用一个np.floor来擦除半个数字:df[“label”]=np.floor(pd.Series(np.where(df[“extension”].diff()<0,0,1)).diff().abs().cumsum()/2)+1
然后df.at[0,“label”]=1
感谢您的时间和帮助。我用了@wwnde的建议,它是有效的。但是谢谢你的帮助!