pandas groupby 然后聚合结果顺序不可重复?
pandas groupby then aggregate results order not repeatable?
这是我的代码:
import pandas as pd
df = pd.DataFrame({'id': ['a', 'a', 'b', 'b', 'b'],
'v1': [1, 2, 3 ,4, 5],
'v2': [7, 6, 5, 4, 3],
'v3': [2, 4, 6, 8, 10]})
df.groupby('id').agg({'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'})
我的问题是,每次我 运行 这段代码(在 jupyter notebook 中),生成的数据帧都有不同的列顺序。这是 pandas 中的错误吗?
我的下一步是重命名生成的数据框,但由于没有可重现的顺序,因此编写可重用代码来执行此操作几乎是不可能的。我该如何解决?
顺便说一句,我正在使用 python 3.5 和 pandas 0.23.0。
谢谢!
当我多次 运行 代码时,我没有得到不同的顺序。但是,如果您 运行 正在解决这个问题,您可以在 agg
之后命名您想要的顺序。例如,如果您想要顺序 v2
、v3
、v1
,请执行:
df.groupby('id',sort=False).agg({'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'})[['v2','v3','v1']]
v2 v3 v1
mean sum count sum
id
a 6.5 6 2 3
b 4.0 24 3 12
或者如果您只是想要与原始数据框相同的顺序:
df.groupby('id',as_index=False).agg({'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'})[df.columns]
id v1 v2 v3
count sum mean sum
0 a 2 3 6.5 6
1 b 3 12 4.0 24
但总而言之,@Allolz 的评论在 IMO 中最有意义,使用 sort_index(1)
:
df.groupby('id').agg({'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'}).sort_index(1)
dict
键在 Python 3.5 中未排序;这适用于代码中 pd.DataFrame()
和 .agg()
中使用的 dict
。您可以使用 Python 标准库中 collections
模块中的 OrderedDict
或者您可以使用 DataFrame.reindex()
重新组织您的列和行,如下所示:
import pandas as pd
df = pd.DataFrame({
'id': ['a', 'a', 'b', 'b', 'b'],
'v1': [1, 2, 3 ,4, 5],
'v2': [7, 6, 5, 4, 3],
'v3': [2, 4, 6, 8, 10]
})
df = df.set_index('id')
df = df.reindex(columns=['v1', 'v2', 'v3'])
df.groupby(level='id').agg({
'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'
})
DataFrame.reindex()
比 DataFrame.sort_index()
.
更通用
这是我的代码:
import pandas as pd
df = pd.DataFrame({'id': ['a', 'a', 'b', 'b', 'b'],
'v1': [1, 2, 3 ,4, 5],
'v2': [7, 6, 5, 4, 3],
'v3': [2, 4, 6, 8, 10]})
df.groupby('id').agg({'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'})
我的问题是,每次我 运行 这段代码(在 jupyter notebook 中),生成的数据帧都有不同的列顺序。这是 pandas 中的错误吗?
我的下一步是重命名生成的数据框,但由于没有可重现的顺序,因此编写可重用代码来执行此操作几乎是不可能的。我该如何解决?
顺便说一句,我正在使用 python 3.5 和 pandas 0.23.0。
谢谢!
当我多次 运行 代码时,我没有得到不同的顺序。但是,如果您 运行 正在解决这个问题,您可以在 agg
之后命名您想要的顺序。例如,如果您想要顺序 v2
、v3
、v1
,请执行:
df.groupby('id',sort=False).agg({'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'})[['v2','v3','v1']]
v2 v3 v1
mean sum count sum
id
a 6.5 6 2 3
b 4.0 24 3 12
或者如果您只是想要与原始数据框相同的顺序:
df.groupby('id',as_index=False).agg({'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'})[df.columns]
id v1 v2 v3
count sum mean sum
0 a 2 3 6.5 6
1 b 3 12 4.0 24
但总而言之,@Allolz 的评论在 IMO 中最有意义,使用 sort_index(1)
:
df.groupby('id').agg({'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'}).sort_index(1)
dict
键在 Python 3.5 中未排序;这适用于代码中 pd.DataFrame()
和 .agg()
中使用的 dict
。您可以使用 Python 标准库中 collections
模块中的 OrderedDict
或者您可以使用 DataFrame.reindex()
重新组织您的列和行,如下所示:
import pandas as pd
df = pd.DataFrame({
'id': ['a', 'a', 'b', 'b', 'b'],
'v1': [1, 2, 3 ,4, 5],
'v2': [7, 6, 5, 4, 3],
'v3': [2, 4, 6, 8, 10]
})
df = df.set_index('id')
df = df.reindex(columns=['v1', 'v2', 'v3'])
df.groupby(level='id').agg({
'v1': ['count', 'sum'],
'v2': 'mean',
'v3': 'sum'
})
DataFrame.reindex()
比 DataFrame.sort_index()
.