gpt4 book ai didi

python - 当一条记录属于多个组时,pandas groupby

转载 作者:搜寻专家 更新时间:2023-10-30 20:52:38 24 4
gpt4 key购买 nike

我希望能够从可以以多种方式分组的数据集中生成汇总统计数据和数据透视表。出现这种情况是因为每个条目可以属于一个分类轴内的多个组(请参见下面的示例)。

到目前为止,我已经找到了一种基于多索引和重复每条记录的次数的解决方案,因为它出现在 category1*category2 组合中。然而,这似乎是不灵活的(我需要检查一个条目是否出现在不同数据源的相同类别中,我可能想添加另一个称为 category3 的类别系统,类别“d”可能会添加到category1 系统等)。而且,它似乎违背了数据库设计的基本原则。

我的问题是:除了我下面的解决方案之外,还有其他(更优雅、更灵活)的方法可以解决这个问题吗?我可以想象保留各种表格,一个包含实际数据,另一个包含分组信息(很像下面的堆栈表)并灵活地使用这些作为 Groupby 的输入,但我不知道这是否可能以及如何制作那个工作。也欢迎任何改进建议。谢谢!

原始数据是这样的:

import pandas

data={'ID' : [1 , 2, 3, 4],
'year' : [2004, 2008 , 2006, 2009],
'money' : [10000 , 5000, 4000, 11500],
'categories1' : [ "a,b,c" , "c" , "a,c" , "" ],
'categories2' : ["one, two" , "one" , "five" , "eight"]}
df= pandas.DataFrame(data)
df.set_index('ID', inplace=True)
print df

给出:

   categories1 categories2  money  year
ID
1 a,b,c one, two 10000 2004
2 c one 5000 2008
3 a,c five 4000 2006
4 eight 11500 2009

我希望能够制作如下所示的数据透视表:

Average money
year 2004 2005 2006 2007
category
a
b
c

还有:

Average money
category2 one two three four
category1
a
b
c

到目前为止,我有:

第一步:使用get_dummies提取类别信息:

cat1=df['categories1'].str.get_dummies(sep=",")
print cat1

给出:

    a  b  c
ID
1 1 1 1
2 0 0 1
3 1 0 1
4 0 0 0

第 2 步:堆叠此:

stack = cat1.stack()
stack.index.names=['ID', 'cat1']
stack.name='in_cat1'
​print stack

给出:

ID  cat1
1 a 1
b 1
c 1
2 a 0
b 0
c 1
3 a 1
b 0
c 1
4 a 0
b 0
c 0
Name: in_cat1, dtype: int64

第 3 步:将其连接到原始数据框以创建多索引数据框

dl = df.join(stack, how='inner')
print dl

看起来像这样:

        categories1 categories2  money  year  in_cat1
ID cat1
1 a a,b,c one, two 10000 2004 1
b a,b,c one, two 10000 2004 1
c a,b,c one, two 10000 2004 1
2 a c one 5000 2008 0
b c one 5000 2008 0
c c one 5000 2008 1
3 a a,c five 4000 2006 1
b a,c five 4000 2006 0
c a,c five 4000 2006 1
4 a eight 11500 2009 0
b eight 11500 2009 0
c eight 11500 2009 0

第 4 步:然后可与 pandas groupby 和 pivot_table 命令一起使用

dl.reset_index(level=1, inplace=True)
pt= dl.pivot_table(values='money', columns='year', index='cat1')
print pt

做我想做的事:

year   2004  2006  2008   2009
cat1
a 10000 4000 5000 11500
b 10000 4000 5000 11500
c 10000 4000 5000 11500

我对 category2 重复了步骤 2 + 3,因此现在数据框具有 3 级索引。

最佳答案

我创建了一个函数,它接受一个 DataFrame 和一个列名。期望列名指定的列有一个可以被','分割的字符串。它会将此拆分附加到具有适当名称的索引。

def expand_and_add(df, col):
expand = lambda x: pd.concat([x for i in x[col].split(',')], keys=x[col].split(','))
df = df.apply(expand, axis=1).stack(0)
df.index.levels[-1].name = col
df.drop(col, axis=1, inplace=1)
return df

现在这将有助于创建 3 层 MultiIndex。我相信操纵 MultiIndex 提供了创建所需枢轴所需的所有灵 active 。

new_df = expand_and_add(expand_and_add(df, 'categories1'), 'categories2')

看起来像:

money    year
ID categories1 categories2
1 a two 10000.0 2004.0
one 10000.0 2004.0
b two 10000.0 2004.0
one 10000.0 2004.0
c two 10000.0 2004.0
one 10000.0 2004.0
2 c one 5000.0 2008.0
3 a five 4000.0 2006.0
c five 4000.0 2006.0
4 eight 11500.0 2009.0

你的枢轴仍然会单独凌乱,但这里有一些。

均值 [categories1, year]

new_df.set_index(ndf.year.astype(int), append=True)['money'].groupby(level=[1, 3]).mean().unstack()

year 2004 2006 2008 2009
categories1
NaN NaN NaN 11500.0
a 10000.0 4000.0 NaN NaN
b 10000.0 NaN NaN NaN
c 10000.0 4000.0 5000.0 NaN

均值 [categories1, categories2]

new_df.groupby(level=[1, 2])['money'].mean().unstack()

categories2 two eight five one
categories1
NaN 11500.0 NaN NaN
a 10000.0 NaN 4000.0 10000.0
b 10000.0 NaN NaN 10000.0
c 10000.0 NaN 4000.0 7500.0

关于python - 当一条记录属于多个组时,pandas groupby,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37350052/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com