在循环中存储结果的更好模式?

Better pattern for storing results in loop?

当我处理数据时,我经常会有一堆类似的对象,我想迭代这些对象来进行一些处理并存储结果。

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.random.randint(0, 1000, 20))
df2 = pd.DataFrame(np.random.randint(0, 1000, 20))

results = []
for df in [df1, df2]:
    tmp_result = df.median()    # do some rpocessing
    results.append(tmp_result)  # append results

我遇到的问题是不清楚结果对应于哪个数据帧。我想过使用对象作为字典的键,但这并不总是有效,因为数据帧不是可哈希对象,不能用作字典的键:

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.random.randint(0, 1000, 20))
df2 = pd.DataFrame(np.random.randint(0, 1000, 20))

results = {}
for df in [df1, df2]:
    tmp_result = df.median()    # do some rpocessing
    results[df] = tmp_result    # doesn't work

我可以想到一些技巧来解决这个问题,比如在循环之前为输入对象定义唯一键,或者将输入和结果作为元组存储在结果列表中。但根据我的经验,这些方法相当笨拙、容易出错,而且我怀疑它们在内存使用方面也不是很好。大多数情况下,我只是使用第一个示例,并确保我小心地手动跟踪结果的位置。

这里是否有针对此问题的明显解决方案或最佳实践?

您可以将原始数据框和结果放在一起 class:

class Whatever:
    def __init__(self, df):
        self.df = df
        self.result = None

whatever1 = Whatever(pd.DataFrame(...))
whatever2 = Whatever(pd.DataFrame(...))

for whatever in [whatever1, whatever2]:
    whatever.result = whatever.df.median()

有很多方法可以根据您的情况进行改进:在构造函数中生成结果,添加一个方法来生成和存储它,从 属性 中动态计算它,等等.

我会连接您的数据帧,为每个数据帧添加一个索引,然后使用分组操作。

pd.concat([df1, df2], keys=['df1', 'df2']).groupby(level=0).median()

如果你的实际处理比较复杂,你可以用.apply()代替.median()

您可以尝试这样的操作:

dd = {'df1': df1,
      'df2': df2}

results_dict = {}
for k, v in dd.items():
    results_dict[k] = v.mean()
results_df = pd.concat(results_dict, keys=results_dict.keys(), axis=1)
print(results_df)

输出:

      df1     df2
0  561.65  549.85

如果你想要相应的输出 dfs ,搜索 SO 以在循环中使用 globals() 看看你是否可以将它们重命名为类似于输入的名称。

对于df1,你可以给它命名

df1.name = 'df1_output'

然后使用globals()将输出df的名称设置为df1.name。然后你会有 df1 和 df1_ouptut