【发布时间】:2017-11-03 04:13:19
【问题描述】:
我正在使用 Pandas 创建一系列数据框,每个数据框都是前一个数据框的聚合版本。 (我有一个必须递归计算的统计数据。)假设我有一系列变量要聚合,保存在名为 aggVars 的字典中。原始数据框df 有嵌套观察:
year area ind occ aggVars
2000 0001 001 001 ...
2000 0001 001 002 ...
2000 0001 002 001 ...
2000 0001 002 002 ...
2000 0002 001 001 ...
2000 0002 001 002 ...
2000 0002 002 001 ...
2000 0002 002 002 ...
2001 0001 001 001 ...
2001 0001 001 002 ...
.
.
.
我想你明白了。观察嵌套在职业中,在行业内,在区域内,在年份内。
我可以用愚蠢的方式做到这一点:
# DUMB CODE BLOCK
df_job = df.groupby(['year', 'area', 'ind', 'occ'], as_index=False)
df_job = df_job.agg(aggVars)
df_work = df_job.groupby(['year', 'area', 'ind'], as_index=False)
df_work = df_work.agg(aggVars)
df_county = df_work.groupby(['year', 'area'], as_index=False)
df_county = df_county.agg(aggVars)
df_year = df_county.groupby(['year'], as_index=False)
df_year = df_year.agg(aggVars)
(我特意为数据框使用了不同的名称,即df_county 而不是df_area,以反映真实数据中的 .groupby() 变量不会如此整齐地映射到层次结构级别。)
我已经测试过了,它工作正常。但这显然是一种愚蠢的做法。这应该是某种循环。 这就是我的麻烦开始的地方。我可以指定一个列表列表:
aggHierarchy = [['job', ['year', 'area', 'ind', 'occ']],
['work', ['year', 'area', 'ind']],
['county', ['year', 'area']],
['year', ['year']]]
然后循环遍历列表,如下所示:
# BROKEN CODE BLOCK
old_df = 'df'
for level in aggHierarchy:
new_df = 'df_%s' % level[0]
new_df = old_df.groupby(level[1], as_index=False)
new_df = new_df.agg(aggVars)
old_df = new_df
这里的逻辑是根据aggHierarchy 元素的第一个子元素分配新数据框的名称,然后使用第二个子元素对事物进行分组。但是,当然,这是行不通的。我编写的循环基本上尝试使用new_df = 'df_%s' % level[0] 为新数据框分配一个名称,但我实际上所做的只是创建一个字符串。
此外,Stack Overflow 上到处都有人指出使用列表在循环中分配变量名是Considered Harmful。我明白了——我可以看出这是多么笨拙。 “Use a dictionary”,我看到人们在写。但事情是这样的:这些数据帧的聚合必须以一定的顺序发生,(我相信)我不能用字典来指定。我无法掌握如何从将变量名添加到字典中,到在循环中以特定顺序调用它们。
这就是我的问题,希望我已经提供了足够的背景信息来很好地说明:给定上面的 DUMB CODE BLOCK 之类的代码块,我需要根据其确切内容的列表(或字典!)来更新变量名称我可能事先不知道...我怎样才能在那里创建某种循环?
【问题讨论】:
-
collections.OrderedDict可能适合您的用例。 -
您是只对 end 结果感兴趣,还是真的需要所有这些中间数据帧来做其他事情?
-
如果您能提供一个工作的最小示例,包括
aggVars的特定名称和值,将会很有帮助,这样就可以看到确切的输入和输出。另外,您需要什么输出 - 您需要所有中间数据帧,还是只需要最后一个(例如您的示例中的df_year)? -
我确实需要中间数据帧。我意识到我可以将大部分
dumb code block折叠成两半,即df_year = df_county.groupby(['year'], as_index=False).agg(aggVars)。 -
一个最小的工作示例可能包含我要聚合的三个变量,例如
white、black和workers。这些保持计数。然后aggVars = {'white': 'sum', 'black': 'sum', 'workers': 'sum'}。然后,每个聚合数据框将保存折叠在分组变量上的总和。 (在这种情况下,您可以从原始数据构建所有中间数据帧,但这不适用于更复杂的统计数据。)