Python Pandas groupby:计算(相对)大小并保存在原始数据帧中
我的数据库结构是这样的:我有属于多个组的单元,并且有不同的变量(对于这个问题,我关注的是一个X)。然后我们有基于年份的记录。所以数据库看起来像Python Pandas groupby:计算(相对)大小并保存在原始数据帧中,python,pandas,Python,Pandas,我的数据库结构是这样的:我有属于多个组的单元,并且有不同的变量(对于这个问题,我关注的是一个X)。然后我们有基于年份的记录。所以数据库看起来像 unitid, groupid, year, X 0 1 1, 1990, 5 1 2 1, 1990, 2 2 2 1, 1991, 3 3 3 2, 1990, 10 year groupid 1961 2000 4
unitid, groupid, year, X
0 1 1, 1990, 5
1 2 1, 1990, 2
2 2 1, 1991, 3
3 3 2, 1990, 10
year groupid
1961 2000 4
2030 3
2040 1
2221 1
2300 2
等等,现在我想做的是测量一些“强度”变量,即每组和每年的单位数量,我想把它放回数据库
到目前为止,我正在做
asd = df.drop_duplicates(cols=['unitid', 'year'])
groups = asd.groupby(['year', 'groupid'])
intensity = groups.size()
然后强度看起来像
unitid, groupid, year, X
0 1 1, 1990, 5
1 2 1, 1990, 2
2 2 1, 1991, 3
3 3 2, 1990, 10
year groupid
1961 2000 4
2030 3
2040 1
2221 1
2300 2
但是,我不知道如何将它们放回旧的数据帧中。我可以通过intensity[0]
访问它们,但是intensity.loc()
给出了LocIndexer不可调用的错误
第二,如果我能测量强度,那将是非常好的。而不是“集团年单位数”,而是“集团年单位数,按该年集团年平均/最大单位数缩放”。如果{t,g}表示组年单元,则为:
也就是说,如果我的简单强度变量(用于时间和组)称为强度(t,g),我想创建相对强度(t,g)=强度(t,g)/mean(强度(t=t,g=:)
——如果这个伪代码有助于我弄清楚
谢谢
更新
为了便于阅读,请(明确地)将答案放在这里。第一部分由
intensity = intensity.reset_index()
df['intensity'] = intensity[0]
是的。您可以通过对结果数据帧调用.reset\u index()
来重置索引。或者,您可以在计算分组操作时禁用它,方法是将指定为groupby()
,例如:
intensity = asd.groupby(["year", "groupid"], as_index=False).size()
至于你的第二个问题,我不知道你在中的意思是什么,而不是“每个组年的单位”,而是“每个组年的单位,按当年每个组年的平均/最大单位进行缩放”。
。如果要通过强度/平均值(强度)
计算“强度”,可以使用变换
方法,如:
asd.groupby(["year", "groupid"])["X"].transform(lambda x: x/mean(x))
这就是你要找的吗
更新
如果要计算强度/平均(强度)
,其中mean(强度)
仅基于year
而非year/groupid
子集,则首先必须仅基于year
创建平均(强度)
,如:
intensity["mean_intensity_only_by_year"] = intensity.groupby(["year"])["X"].transform(mean)
然后计算所有year/groupid
子集的强度/平均值(强度)
,其中平均值(强度)
仅从year
子集得出:
intensity["relativeIntensity"] = intensity.groupby(["year", "groupid"]).apply(lambda x: pd.DataFrame(
{"relativeIntensity": x["X"] / x["mean_intensity_only_by_year"] }
))
也许这就是你想要的,对吧?事实上,几天后,我发现这个双重问题的第一个答案是错误的。也许有人可以详细说明
.size()
实际上做了什么,但这只是为了防止有人用谷歌搜索这个问题时没有走错我的路
结果是.size()
的行数比原始对象少得多(如果我使用reset\u index()
,尽管我试图将大小堆叠回原始对象,但仍有许多行保留了NaN
groups = asd.groupby(['year', 'groupid'])
intensity = groups.apply(lambda x: len(x))
asd.set_index(['year', 'groupid'], inplace=True)
asd['intensity'] = intensity
或者,我们也可以这样做
groups = asd.groupby(['fyearq' , 'sic'])
# change index to save groupby-results
asd= asd.set_index(['fyearq', 'sic'])
asd['competition'] = groups.size()
我的问题的第二部分是通过
# relativeSize
def computeMeanInt(group):
group = group.reset_index()
# every group has exactly one weight in the mean:
sectors = group.drop_duplicates(cols=['group'])
n = len(sectors)
val = sum(sectors.competition)
return float(val) / n
result = asd.groupby(level=0).apply(computeMeanInt)
asd= asd.reset_index().set_index('fyearq')
asd['meanIntensity'] = result
# if you don't reset index, everything crashes (too intensive, bug, whatever)
asd.reset_index(inplace=True)
asd['relativeIntensity'] = asd['intensity']/asd['meanIntensity']
在我消化第一部分之前,快速反馈到第二部分:几乎。我想要平均值(x),但不是整个数据集的平均值(x),而是同一年数据的平均值(x)。
mean(x)
是基于组而不是整个数据集计算的。因此在本例中,每个mean(x)
是根据每个year/groupid
子集计算的。或者你可能只想根据year
来计算,而不是只根据year/groupid
组合?year来计算。这应该是关于“强度”的,就像问题的第一部分一样。我刚刚注意到了这一点(更紧急)问题,我其实不需要介绍X-这有帮助吗?更新。至于“强度”,我只是知道它是关于物理的,但我对它知之甚少或一无所知。。。