【问题标题】:pandas - include all column and row pair valuespandas - 包括所有列和行对值
【发布时间】:2018-02-02 22:35:38
【问题描述】:

我有一个缺少大量数据的数据集。示例数据文件:

a,b,c,w
a1,,,
a2,b1,c1,
a2,b1,c2,
a2,,,
a3,b2,c3,
a4,,,
a5,b1,c1,100
a6,b2,c4,
a7,b1,c2,214.285714285714
a7,b1,c2,245.454545454545
a7,b1,c2,292.105263157895
a7,b1,c2,
a8,b1,c2,
a9,b2,c3,
,b3,,
,,c4,
,,c5,

我正在努力创建一个如下所示的数据透视表:

         w
      mean
a       a1  a2  a3  a4     a5  a6          a7  a8  a9
b  c
       NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
b1 c1  NaN NaN NaN NaN  100.0 NaN         NaN NaN NaN
b1 c2  NaN NaN NaN NaN    NaN NaN  250.615174 NaN NaN
b2 c3  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
b2 c4  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
b3     NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
   c4  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
   c5  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN

我不在乎空白是在顶部还是底部。关键是每个 A 值都显示为一列,而对于行,只显示现有的 B、C 对。

以下代码:

dataframe = pd.read_csv('test/data/sparse.csv')
pd.set_option('display.width', 1000)
print(dataframe)
col_names = ['a']
row_names = ['b', 'c']
value_names = ['w']
aggregates = {'w': ['mean']}

pivot = pd.pivot_table(
    dataframe,
    index=row_names,
    columns=col_names,
    values=value_names,
    aggfunc=aggregates
)

创建一个像这样的数据透视表:

           w
        mean
a         a5          a7
b  c
b1 c1  100.0         NaN
   c2    NaN  250.615174
b2 c3    NaN         NaN
   c4    NaN         NaN

如果我将所有 None 值设置为空白,通过:

for c in dataframe:
    if str(dataframe[c].dtype) in ('object', 'string_', 'unicode_'):
        dataframe[c].fillna(value='', inplace=True)

然后我得到

           w            
        mean            
a         a5          a7
b  c                    
         NaN         NaN
   c4    NaN         NaN
   c5    NaN         NaN
b1 c1  100.0         NaN
   c2    NaN  250.615174
b2 c3    NaN         NaN
   c4    NaN         NaN
b3       NaN         NaN

这让我得到我的行但不是我的列。如果我将 dropna=False 添加到 pivot_table 调用中,那么我会得到所有列,但也会得到原始数据集中不存在的行对。

有什么建议吗?

谢谢

【问题讨论】:

    标签: python pandas dataframe pivot-table


    【解决方案1】:

    如果您可以使用 nan 而不是空格,那么 groupby + unstack 可以在这里使用。首先,使用astype(str) 将列abc 转换为字符串。这将导致groupby 在分组数据时不再忽略 NaN。

    cols = ['a', 'b', 'c']
    df[cols] = df[cols].astype(str)
    
    df.groupby(cols)\
      .w.mean()\
      .unstack(0)\
      .drop('nan', 1)
    
    a        a1  a2  a3  a4     a5  a6          a7  a8  a9
    b   c                                                 
    b1  c1  NaN NaN NaN NaN  100.0 NaN         NaN NaN NaN
        c2  NaN NaN NaN NaN    NaN NaN  250.615174 NaN NaN
    b2  c3  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
        c4  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
    b3  nan NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
    nan c4  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
        c5  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
        nan NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
    

    【讨论】:

    • OP 包含了nan nan 行,所以groupby unstack 就是dataframe.groupby(cols).mean().unstack(0)
    • 谢谢。干净整洁。
    【解决方案2】:

    达到目标输出的一种方法是将所有独特的 bc 对收集为元组:

    tups = df[['b', 'c']].drop_duplicates().apply(tuple, axis=1)
    
    # 0     (nan, nan)
    # 1       (b1, c1)
    # 2       (b1, c2)
    # 4       (b2, c3)
    # 7       (b2, c4)
    # 14     (b3, nan)
    # 15     (nan, c4)
    # 16     (nan, c5)
    

    ...然后使用dropna=True 调用.pivot_table,并立即使用您的 b-c 元组重新索引:

    df.pivot_table( \
      index=['b', 'c'], columns='a', aggfunc='mean', dropna=False \ 
      ).reindex(tups)
    
    #           w                                           
    # a        a1  a2  a3  a4     a5  a6          a7  a8  a9
    # NaN NaN NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
    # b1  c1  NaN NaN NaN NaN  100.0 NaN         NaN NaN NaN
    #     c2  NaN NaN NaN NaN    NaN NaN  250.615174 NaN NaN
    # b2  c3  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
    #     c4  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
    # b3  NaN NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
    # NaN c4  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
    #     c5  NaN NaN NaN NaN    NaN NaN         NaN NaN NaN
    

    【讨论】:

      猜你喜欢
      • 2018-04-03
      • 2019-03-02
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 2015-05-29
      • 2021-07-27
      相关资源
      最近更新 更多