使用Python/Pandas/Numpy计算图形/绘图中的循环数

使用Python/Pandas/Numpy计算图形/绘图中的循环数,python,pandas,numpy,dataframe,matplotlib,Python,Pandas,Numpy,Dataframe,Matplotlib,如何通过使用python/pandas/numpy库在matplotlib中绘制的图形,找出Y值(速度)从700-800 RPM上升和下降到1600-1800 RPM,反之亦然的次数。我使用matplotlib和dataframe绘制了此图 预期输出应为--> 从附图看,速度上升的坡道数量=2,下降的坡道数量=2 更多说明,请参见下面的附图/图表 #状态变量 递减=假 增加=错误 上面最后一个_=假 下面的最后一个_=False 丢弃计数=0 跳转计数=0 对于df中的rpm_str: rpm

如何通过使用python/pandas/numpy库在matplotlib中绘制的图形,找出Y值(速度)从700-800 RPM上升和下降到1600-1800 RPM,反之亦然的次数。我使用matplotlib和dataframe绘制了此图

预期输出应为--> 从附图看,速度上升的坡道数量=2,下降的坡道数量=2

更多说明,请参见下面的附图/图表

#状态变量
递减=假
增加=错误
上面最后一个_=假
下面的最后一个_=False
丢弃计数=0
跳转计数=0
对于df中的rpm_str:
rpm=int(rpm_str)#因为OP指示数据是字符串
#跨越门槛
如果((最后一个_低于或降低)且rpm<700):
下降计数=下降计数+1
递减=假
下面的最后一个_=False
elif((最后一个_高于或增加)和rpm>1600):
跳转计数=跳转计数+1
增加=错误
上面最后一个_=假
如果(最后一个_以上且转速<1600):
递减=真
增加=错误
elif(低于最后一个单位且转速>700):
递增=真
递减=假
#陈述
下面的最后一个_=False
上面最后一个_=假
如果(rpm<700):
下面的最后一个_=真
elif(转速>1600转/分):
上面最后一个字母=真

这不是一个完美的解决方案,可能会错过一些边缘情况,但您的数据看起来非常正常

请尝试以下代码:

y
是y数据(rpm)
lim
是循环开始时的rpm量

cycles = 0
for i in range(len(y)):
    if y[i] >= lim:
        cycles += 1
        while y[i] >= lim:
            i += 1

以下是矢量化解决方案:

import pandas as pd

df = pd.DataFrame({'speed': [0,1600,0,1600,1600,1600,0,0,0]})

# Check if values are above or below a threshold
threshold = 1500
df['over_threshold'] = df['speed'] > threshold

# Compare to the previous row
# If over_threshold has changed, 
# then you either went above or fell below the threshold
df['changed'] = df['over_threshold'] != df['over_threshold'].shift(1)

# First one has, by definition, has no previous value, so we should omit it
df = df.loc[1:,]

# Count how many times a row is newly above or below threshold
counts = df.loc[df['changed']].groupby('over_threshold').agg({'changed': 'count'})
counts.index = ["Down", "Up"]
counts.columns = ["Count"]
counts

#     Count
#Down   2
#Up     2

然后,您将计算您爬升或下降的次数。

df.speed是什么样子的?它只是一个整数列表吗?是的,它只是一个整数值。有关更多说明,请参阅随附的图像文件。@您可以使用
df.speed
的时间导数,只检查符号更改了多少次。我不知道你的真实数据有多不稳定,但从图像上看,斜坡看起来很干净,这样方法就可以工作了。@Guimoute:如果我在这里绘图,真实数据太大,太复杂,很难理解。这就是我基于1天数据绘制图表的原因。您可以在
if
中弹出括号,也可以在此处使用一些
elif
)@Guimoute当涉及到像这样的状态机时,我尽量避免使用elif,因为我经常在不应该的时候使用它们,哈哈,但它们在这里会有所帮助。另外,我喜欢括号,因为我来自其他语言,python不是我的第一个。@ZacharyOldham:我的数据集很大,但我试图用一天的数据来计算它。如果它有效,那么我将使用类似的逻辑来完成数据。我试图在Jupyter笔记本中运行上述脚本,但我有以下错误。!'这可能类似于df中rpm的
。speed
或df中rpm的
[“speed”]
?@Analyst您是否从文件中读取值并没有强制转换它们?
lim
在测试时还不存在。感谢您的代码。您的代码运行良好,但我没有得到预期的结果。它给出了数据帧中每个点(1秒数据)的总计数w.r.t。如果您查看附件中的图表,那么预期输出应该是…上升次数=2,下降次数=2。我更新了代码,以包含一些虚拟数据,并澄清输出显示2个上升和2个下降。谢谢,考虑到您的df,您的代码是正确的。我想计算一下从700转/分到1600转/分的提速次数和从1600转/分到700转/分的减速次数。如果速度从700增加到800或从1600减少到1500,则不应将跳跃计算在内,即“向上/向下=0”。如果速度以700、900、1400、1600等步长从700增加到1600,则应计算“向上=1”,而不是3,反之亦然(不应计算在速度增加或降低之间)。如果您查看附件中的图像文件,您将得到更多的澄清。当且仅当速度差大于或等于900 RPM,即(1600-700)RPMe时,向上=1或向下=1。g df=pd。上述df预期输出的数据帧({'engspd':[0500700001200120017001700160000700600800900700130001190019001600010010010011100700700700,0]})应为:向上=2,向下=2
cycles = 0
for i in range(len(y)):
    if y[i] >= lim:
        cycles += 1
        while y[i] >= lim:
            i += 1
import pandas as pd

df = pd.DataFrame({'speed': [0,1600,0,1600,1600,1600,0,0,0]})

# Check if values are above or below a threshold
threshold = 1500
df['over_threshold'] = df['speed'] > threshold

# Compare to the previous row
# If over_threshold has changed, 
# then you either went above or fell below the threshold
df['changed'] = df['over_threshold'] != df['over_threshold'].shift(1)

# First one has, by definition, has no previous value, so we should omit it
df = df.loc[1:,]

# Count how many times a row is newly above or below threshold
counts = df.loc[df['changed']].groupby('over_threshold').agg({'changed': 'count'})
counts.index = ["Down", "Up"]
counts.columns = ["Count"]
counts

#     Count
#Down   2
#Up     2