如何停止“记住”旧值的数据框子集

时间:2018-08-01 16:16:25

标签: python pandas group-by

很抱歉,这是奇怪的措词,但我不知道该如何更好地描述它。我将把我的问题翻译成美国的术语,以便于理解。我的问题是,我有一个包含州和地区的国家数据库,我只需要与佛罗里达州的地区合作,所以我要这样做:

df_fl=df.loc[df.state=='florida'].copy()

经过一些转换后,我想获取佛罗里达州每个地区的均值,所以我这样做:

df_final=df_fl.groupby(['district']).mean()

但这会为数据库中的每个分区带来一个数据框。来自非佛罗里达州地区的所有行都填充了nans。我想对此有一个简单的解决方案,但我一直找不到。这也有点反直觉。

那么,您能帮我解决这个问题吗?

预先感谢

编辑: 我的数据看起来像这样:

District   state      Salary
   1        Florida    1000
   1        Florida    2000
   2        Florida    2000
   2        Florida    3000
   3        California 3000

df_fl如下所示:

District   state      Salary
   1        Florida    1000
   1        Florida    2000
   2        Florida    2000
   2        Florida    3000

申请后

df_final=df_fl.groupby(['district']).mean()

我希望得到这个:

District   Salary
   1        1500
   2        2500

但是我得到了:

District   Salary
   1        1500
   2        2500
   3         nan

显然是非常简化的版本,但核心仍然存在。

2 个答案:

答案 0 :(得分:5)

这是因为您的'District'列是分类类型。

MCVE

df = pd.DataFrame(dict(
    State=list('CCCCFFFF'),
    District=list('WXWXYYZZ'),
    Value=range(1, 9)
))

没有分类

df.query('State == "F"').groupby('District').Value.mean()

District
Y    5.5
Z    7.5
Name: Value, dtype: float64

带有绝对

df.assign(
    District=pd.Categorical(df.District)
).query('State == "F"').groupby('District').Value.mean()

District
W    NaN
X    NaN
Y    5.5
Z    7.5
Name: Value, dtype: float64

解决方案

许多方法可以做到这一点。保留分类类型的一种方法是使用方法remove_unused_categories

df = df.assign(District=df.District.cat.remove_unused_categories())

答案 1 :(得分:3)

正如piRSquared所述,这仅在分类数据中发生。从0.23.0 groupby开始,有一个新的“ observed”自变量可切换此行为。来自piRSquared的MCVE:

>>> df = pd.DataFrame(dict(
    State=list('CCCCFFFF'),
    District=list('WXWXYYZZ'),
    Value=range(1, 9)
))
>>> df.assign(
    District=pd.Categorical(df.District)
).query('State == "F"').groupby('District').Value.mean()
District
W    NaN
X    NaN
Y    5.5
Z    7.5
Name: Value, dtype: float64
>>> df.assign(
    District=pd.Categorical(df.District)
).query('State == "F"').groupby('District', observed=True).Value.mean()
District
Y    5.5
Z    7.5
Name: Value, dtype: float64