我有以下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)
但是每个结果可能有数百个数据点,我觉得这种解决方案将很快使数百或数千个其他列的数据帧膨胀。
我可能需要直接比较两行之间的diff
(即,如果“部门1”小于“部门2”),我无法弄清楚如何使用上述解决方案。>
由于要处理的数据量大,我主要担心速度,但也希望避免不必要的内存使用。
进行此类计算的最佳方法是什么?
答案 0 :(得分:1)
旋转在这里可能是一种不错的方法:
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
您现在可以在列中获得分度的值,这将使比较更加容易。
我也可以尝试unstack
。它的通用性较差,但可以使用时效率更高。在我的测试中,速度快了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