【问题标题】:Python pandas pyhaystackPython 熊猫 pyhaystack
【发布时间】:2018-07-30 04:36:48
【问题描述】:

我正在使用一个名为 pyhaystack 的模块从基于“标签”的楼宇自动化系统中检索数据(其余 API)。 Python 将返回数据字典。我试图将熊猫与下面的 If Else 语句一起使用,但我遇到了麻烦。 pyhaystack 可以很好地获取数据...

这将我连接到自动化系统:(工作正常)

from pyhaystack.client.niagara import NiagaraHaystackSession
import pandas as pd

session = NiagaraHaystackSession(uri='http://0.0.0.0', username='Z', password='z', pint=True)

此代码找到我的名为“znt”的标签,将字典转换为 Pandas,并过滤时间:(这两个点都很好)

znt = session.find_entity(filter_expr='znt').result
znt = session.his_read_frame(znt, rng= '2018-01-01,2018-02-12').result
znt = pd.DataFrame.from_dict(znt)


znt.index.names=['Date']
znt = znt.fillna(method = 'ffill').fillna(method = 'bfill').between_time('08:00','17:00')

我最感兴趣的是列名,最终我希望Python根据条件返回列名:

print(znt.columns)
print(znt.values)

返回:

Index(['C.Drivers.NiagaraNetwork.Adams_Friendship.points.A-Section.AV1.AV1ZN~2dT', 'C.Drivers.NiagaraNetwork.points.A-Section.AV2.AV2ZN~2dT'], dtype='object')

[[ 65.9087  66.1592]
 [ 65.9079  66.1592]
 [ 65.9079  66.1742]
 ..., 
 [ 69.6563  70.0198]
 [ 69.6563  70.2873]
 [ 69.5673  70.2873]]

我对 Pandas 数据框的这个名称最感兴趣。 C.Drivers.NiagaraNetwork.Adams_Friendship.points.A-Section.AV1.AV1ZN~2dT

对于我的两个数组,我将数据框中的数据减去 70 的值。 (工作得很好)

znt_sp = 70

deviation = znt - znt_sp

deviation = deviation.abs()

deviation

这就是我在 Pandas 中被绊倒的地方。如果偏差大于四,我希望​​ Python 打印列的名称,否则打印这个区域是正常的。任何提示将不胜感激..

if (deviation > 4).any():
    print('Zone %f does not make setpoint' % deviation)

else:
    print('Zone %f is Normal' % deviation)

Pandas 中的列名是: C.Drivers.NiagaraNetwork.Adams_Friendship.points.A-Section.AV1.AV1ZN~2dT

【问题讨论】:

    标签: python python-3.x pandas data-science


    【解决方案1】:

    我认为 DataFrame 将是处理您想要的东西的好方法。 从 znt 开始,您可以在那里进行所有计算:

    deviation = znt - 70
    deviation = deviation.abs()
    
    # and the cool part is filtering in the df
    problem_zones = 
        deviation[deviation['C.Drivers.NiagaraNetwork.Adams_Friendship.points.A-
        Section.AV1.AV1ZN~2dT']>4]
    

    您可以使用它并找出一种遍历列的方法,例如:

    for each in df.columns:
        # if in this column, more than 10 occurences of deviation GT 4...
        if len(df[df[each]>4]) > 10:
            print('This zone have a lot of troubles : ', each)
    

    编辑

    我喜欢向 DataFrame 添加列,而不仅仅是构建外部系列。

    df[‘error_for_a’] = df[a] - 70
    

    这打开了可能性并将所有东西放在一起。可以使用

    df[df[‘error_for_a’]>4]
    

    同样,all() 或 any() 可能很有用,但在现实生活中,当出现一定数量的错误时,我们可能需要触发“故障检测”。

    如果时间表已设置为上午 8 点“已占用”.... 可能第一个条目将不正确....(即使 30 分钟后情况好转,任何条目都会触发错误)。另一种情况是错误很小的会议室......但是一旦有人在里面......事情就会变糟(all()不会看到)。

    【讨论】:

      【解决方案2】:

      解决方案:
      你可以遍历columns

      for col in df.columns:
          if (df[col] > 4).any(): # or .all if needed 
              print('Zone %s does not make setpoint' % col)
          else:
              print('Zone %s is Normal' % col)
      

      或者通过定义一个函数并使用apply

      def _print(x):
          if (x > 4).any():
              print('Zone %s does not make setpoint' % x.name)
          else:
              print('Zone %s is Normal' % x.name)
      
      df.apply(lambda x: _print(x))
      # you can even do
      [_print(df[col]) for col in df.columns]
      

      建议: 也许您会将结果保存在另一个结构中,更改函数以返回“正常”的布尔系列:

      def is_normal(x):
          return not (x > 4).any()
      
      s = df.apply(lambda x: is_normal(x))
      
      # or directly
      s = df.apply(lambda x: not (x > 4).any())
      

      它将返回一系列s,其中index 是您的df 的列名,values 是与您的条件相对应的布尔值。

      然后您可以使用它来获取所有正常列名称s[s].index 或非正常列名称s[~s].index

      例如:我只想要我的 df 的普通列:df[s[s].index]


      一个完整的例子
      对于示例,我将使用与您的条件不同的示例df(我检查是否没有元素低于 4 - 正常,否则不设定设定值)

      df = pd.DataFrame(dict(a=[1,2,3],b=[2,3,4],c=[3,4,5])) # A sample
      
      print(df)
         a  b  c
      0  1  2  3
      1  2  3  4
      2  3  4  5
      

      您的用例:打印是否正常 - 解决方案

      for col in df.columns:
      if (df[col] < 4).any():
          print('Zone %s does not make setpoint' % col)
      else:
          print('Zone %s is Normal' % col)
      

      结果

      Zone a is Normal
      Zone b is does not make setpoint
      Zone c is does not make setpoint
      

      为了说明我的建议is_normal 列保持在一个系列中

      s = df.apply(lambda x: not (x < 4).any()) # Build the series
      print(s)
      
      a     True
      b     False
      c     False
      dtype: bool
      
      
      print(df[s[~s].index]) #Falsecolumns df
         b  c
      0  2  3
      1  3  4
      2  4  5
      
      
      print(df[s[s].index]) #Truecolumns df
         a
      0  1
      1  2
      2  3
      

      【讨论】:

      • 不知道 .any() 函数。这很酷,我会重复使用。唯一的缺点是只有 1 个偏差会触发该区域未达到设定点的消息。
      • 嘿,伙计们,我仍在尝试消化这些信息,并且我想对在 if else 语句中添加箱形图的相同想法添加一个额外的转折。你能帮我写这篇基本相同的帖子吗?再次感谢任何关于熊猫系列 Vs datafame 的建议,非常感谢,我学到了很多东西。 stackoverflow.com/questions/48908828/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多