Pandas groupby 为零值

Posted

技术标签:

【中文标题】Pandas groupby 为零值【英文标题】:Pandas groupby for zero values 【发布时间】:2016-08-28 10:30:18 【问题描述】:

我在 csv 文件中有这样的数据

Symbol  Action  Year
  AAPL     Buy  2001
  AAPL     Buy  2001
   BAC    Sell  2002
   BAC    Sell  2002

我可以像这样阅读它和分组

df.groupby(['Symbol','Year']).count()

我明白了

             Action
Symbol Year        
AAPL   2001       2
BAC    2002       2

我想要这个(顺序无关紧要)

             Action
Symbol Year        
AAPL   2001       2
AAPL   2002       0
BAC    2001       0
BAC    2002       2

我想知道是否可以将出现次数归零

【问题讨论】:

【参考方案1】:

你可以用这个:

df = df.groupby(['Symbol','Year']).count().unstack(fill_value=0).stack()
print (df)

输出:

             Action
Symbol Year        
AAPL   2001       2
       2002       0
BAC    2001       0
       2002       2

【讨论】:

这是一个不错的解决方案!优雅直观,比使用 pivot_table 更好,除非后者有任何优势或特定用例。你知道吗? 这是否只对一组对象有效?它似乎不起作用,它正在给我 AttributeError: 'Series' object has no attribute 'stack'【参考方案2】:

您可以将pivot_tableunstack 一起使用:

print df.pivot_table(index='Symbol', 
                     columns='Year', 
                     values='Action',
                     fill_value=0, 
                     aggfunc='count').unstack()

Year  Symbol
2001  AAPL      2
      BAC       0
2002  AAPL      0
      BAC       2
dtype: int64

如果您需要输出为DataFrame,请使用to_frame

print df.pivot_table(index='Symbol', 
                     columns='Year', 
                     values='Action',
                     fill_value=0, 
                     aggfunc='count').unstack()
                                     .to_frame()
                                     .rename(columns=0:'Action')

             Action
Year Symbol        
2001 AAPL         2
     BAC          0
2002 AAPL         0
     BAC          2

【讨论】:

这会生成一个漂亮的数据透视表,但使用 fill_value=0 仍然不会显示计数为 0 的行。我认为 fill_value 仅适用于缺少数据或 NaN 的行? 是参数fill_value替换NaN为0。【参考方案3】:

数据类型类别

也许这个功能在这个线程打开时不存在,但是数据类型“类别”可以在这里提供帮助:

# create a dataframe with one combination of a,b missing
df = pd.DataFrame("a":[0,1,1], "b": [0,1,0])
df = df.astype("a":"category", "b":"category")
print(df)

数据框如下所示:

   a  b
0  0  0
1  1  1
2  1  0

现在,按 a 和 b 分组

print(df.groupby(["a","b"]).size())

产量:

a  b
0  0    1
   1    0
1  0    1
   1    1

注意最右边一列中的 0。这种行为也记录在pandas userguide 中(在页面上搜索“groupby”)。

【讨论】:

我在不需要零的时候遇到这种情况!【参考方案4】:

如果您想在不使用 pivot_table 的情况下执行此操作,可以尝试以下方法:

midx = pd.MultiIndex.from_product([ df['Symbol'].unique(), df['Year'].unique()], names=['Symbol', 'Year'])
df_grouped_by = df_grouped_by.reindex(midx, fill_value=0)

我们在上面所做的实际上是创建一个多索引,将所有可能的值乘以两列,然后使用该多索引将零填充到我们的 group-by 数据帧中。

【讨论】:

这会将所有计数设置为零,而不是那些未出现在数据中的计数【参考方案5】:

第 1 步:创建一个数据框,将每个非零类的计数存储在 counts

列中
count_df = df.groupby(['Symbol','Year']).size().reset_index(name='counts')

第 2 步:现在使用 pivot_table 获取所需的数据帧,其中包含现有和不存在类的计数。

df_final = pd.pivot_table(count_df,
                       index=['Symbol','Year'],
                       values='counts',                            
                       fill_value = 0,
                       dropna=False,
                       aggfunc=np.sum)

现在可以使用命令将计数值提取为列表

list(df_final['counts'])

【讨论】:

以上是关于Pandas groupby 为零值的主要内容,如果未能解决你的问题,请参考以下文章

Python、Pandas:GroupBy 属性文档

python [groupby]示例groupby #pandas #secret

Pandas高级教程之:GroupBy用法

Pandas 的groupby操作

从 Pandas groupBy 到 PySpark groupBy

pandas如何对value列数据进行分组groupby?