Python 跨多个唯一行计算结果

Python 跨多个唯一行计算结果,python,pandas,Python,Pandas,我有以下MVCE: import pandas as pd data_in = [ { 'foo': 'company A', 'bar': 'division 1', 'time': 1, 'diff': 0.99 }, { 'foo': 'company A', 'bar': 'division 1', 'time': 2, 'diff': 0.95 }, { 'foo': 'company A', 'bar': 'division 1', 'time': 3, 'diff':

我有以下MVCE:

import pandas as pd

data_in = [
  { 'foo': 'company A', 'bar': 'division 1', 'time': 1, 'diff': 0.99 },
  { 'foo': 'company A', 'bar': 'division 1', 'time': 2, 'diff': 0.95 },
  { 'foo': 'company A', 'bar': 'division 1', 'time': 3, 'diff': 0.94 },
  { 'foo': 'company A', 'bar': 'division 1', 'time': 4, 'diff': 0.90 },
  { 'foo': 'company A', 'bar': 'division 1', 'time': 5, 'diff': 1.01 },

  { 'foo': 'company A', 'bar': 'division 2', 'time': 1, 'diff': 0.91 },
  { 'foo': 'company A', 'bar': 'division 2', 'time': 2, 'diff': 0.92 },
  { 'foo': 'company A', 'bar': 'division 2', 'time': 3, 'diff': 0.93 },
  { 'foo': 'company A', 'bar': 'division 2', 'time': 4, 'diff': 0.94 },
  { 'foo': 'company A', 'bar': 'division 2', 'time': 5, 'diff': 0.95 },

  { 'foo': 'company B', 'bar': 'division 1', 'time': 1, 'diff': 1.01 },
  { 'foo': 'company B', 'bar': 'division 1', 'time': 2, 'diff': 1.08 },
  { 'foo': 'company B', 'bar': 'division 1', 'time': 3, 'diff': 1.21 },
  { 'foo': 'company B', 'bar': 'division 1', 'time': 4, 'diff': 1.22 },
  { 'foo': 'company B', 'bar': 'division 1', 'time': 5, 'diff': 1.18 },

  { 'foo': 'company B', 'bar': 'division 2', 'time': 1, 'diff': 0.81 },
  { 'foo': 'company B', 'bar': 'division 2', 'time': 2, 'diff': 0.82 },
  { 'foo': 'company B', 'bar': 'division 2', 'time': 3, 'diff': 0.88 },
  { 'foo': 'company B', 'bar': 'division 2', 'time': 4, 'diff': 0.87 },
  { 'foo': 'company B', 'bar': 'division 2', 'time': 5, 'diff': 0.87 },
]

df = pd.DataFrame(data_in).set_index(['foo', 'bar', 'time'])
df.sort_index(axis=0, inplace=True)

data_out = []
for name, group in df.groupby(['foo', 'time']):

  print(group) 
# example output
# foo       bar        time
# company B division 1 5     1.18
#           division 2 5     0.87
  result = '?'
  data_out.append({ 'foo': name[0], 'time': name[1], 'result': result })

print('out', data_out)
基本上,我试图通过比较两个部门来计算每个公司的一些结果,每次我们记录
diff

例如,我试图得到一个真实的结果,当“第1部分”在目标度量之上执行时,以及当“第2部分”在标准目标之下执行时

我找到的一个可能的解决办法是

for name, group in df.groupby(['foo', 'time']):
  group = group.reset_index()

  group.loc[(group['bar'] =="division 1") & (group['diff'] > 1.04), 'result'] = True
  group.loc[(group['bar'] =="division 2") & (group['diff'] < 1), 'result'] = True
  group['result'] = group['result'].fillna(False)
  result = group['result'].all(skipna=False)
df.groupby(['foo','time'])中的组名称: 组=组。重置索引() group.loc[(组['bar']=“第1部分”)&组['diff']>1.04),'result']=True group.loc[(组['bar']=“第2分部”)&组['diff']<1],'result']=True 组['result']=组['result'].fillna(False) 结果=组['result']。全部(skipna=False) 然而,每个结果可能有数百个数据点,我觉得这个解决方案会很快用数百或数千个额外的列填充数据帧

我可能需要直接比较两行之间的
diff
(即,如果“第1部分”小于“第2部分”),我无法找出如何使用上述解决方案

由于要处理的数据量很大,我主要关心速度,但也希望避免任何不必要的内存使用

对于这些类型的计算,最好的方法是什么?

在这里,旋转可能是一种很好的方法:

df.pivot_table(index=['foo', 'time'], columns='bar', values='diff')
给出:

bar             division 1  division 2
foo       time                        
company A 1           0.99        0.91
          2           0.95        0.92
          3           0.94        0.93
          4           0.90        0.94
          5           1.01        0.95
company B 1           1.01        0.81
          2           1.08        0.82
          3           1.21        0.88
          4           1.22        0.87
          5           1.18        0.87
现在,在列中有了分区的值,这将使比较更容易


我也可以尝试取消堆叠。它的通用性较低,但在可以使用时效率要高得多。在我的测试中,速度快了7倍多:

df.unstack(1)
                     diff           
bar            division 1 division 2
foo       time                      
company A 1          0.99       0.91
          2          0.95       0.92
          3          0.94       0.93
          4          0.90       0.94
          5          1.01       0.95
company B 1          1.01       0.81
          2          1.08       0.82
          3          1.21       0.88
          4          1.22       0.87
          5          1.18       0.87

带mvce的熊猫问题!哭喊快乐的眼泪美丽的方法,适合我所有的测试案例:)谢谢!