【问题标题】:Create a pivot table using two columns treating them as a group使用将它们视为一个组的两列创建数据透视表
【发布时间】:2020-11-13 13:58:00
【问题描述】:

我已经看到了很多解决使用单个列作为索引复制 R 的 dcast 功能的答案,但是我很难复制一个 dcast,您将列组合起来,然后进行旋转。当我尝试使用 pivot_table 或 crosstab 时,我总是遇到问题,我最终会丢失列或混淆名称。

我有一个如下所示的 DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({'class': ['History', 'History', 'English','Math','Gym', 'Gym'], 
                   'first': ['John','Mary','John', 'Charles', 'John', 'Charles'], 
                   'last': ['Smith', 'Jones', 'Smith', 'Right', 'Smith', 'Right'], 
                   'grade': ['1','2','1','3', np.nan, np.nan] })

     class    first   last grade
0  History     John  Smith     1
1  History     Mary  Jones     2
2  English     John  Smith     1
3     Math  Charles  Right     3
4      Gym     John  Smith   NaN
5      Gym  Charles  Right   NaN

当我尝试创建先分组和最后分组的数据透视表时,它会创建一个表,但不会将名称分组在一起。它使用第一个和最后一个的所有组合创建行:

df2 = df.pivot_table(index=['first', 'last'], 
                     columns=['class'], 
                     aggfunc={'grade': max}, 
                     dropna=False).fillna(0)

                grade
class         English Gym History Math
first   last
Charles Jones       0   0       0    0
        Right       0   0       0    3
        Smith       0   0       0    0
John    Jones       0   0       0    0
        Right       0   0       0    0
        Smith       1   0       1    0
Mary    Jones       0   0       2    0
        Right       0   0       0    0
        Smith       0   0       0    0

我正在尝试复制 R 的 dcast 的行为:

df2 <- dcast.data.table(df,first + last  ~ class, value.var ='grade')
   first   last     English  Gym       History Math
1: Charles Right    <NA>     <NA>      <NA>    3
2:    John Smith    1        <NA>      1       <NA>
3:    Mary Jones    <NA>     <NA>      2       <NA>

我意识到如果我设置 dropna=True 它只会删除多余的行,但它也会删除其中包含 NaN 的列,我不希望这样。我需要保留这些列。

【问题讨论】:

  • 我看到这是由于重复而关闭的,但没有一个处理我正在处理的这个特殊问题。在创建数据透视表时,我没有看到他们中的任何人尝试将两列作为一个组使用。
  • pd.crosstab(columns=df['class'],index=[df["first"],df["last"]], values = df['grade'], aggfunc={max})
  • “如果您认为您的问题不是重复的,那么 edit 您的问题以澄清它有何不同以及为什么其他答案都不适用。”不要让反对票让您失望。他们不是针对您,而只是用户表达了他们的意见,即不应该问这个问题,因为有多个重复项。如果您按照我的建议进行编辑和澄清,我将愿意重新提出问题,并将成为第一个投票的人。干杯。
  • 您发布的交叉表示例的问题在于,它会删除 Gym 列,除非您指定 dropna=False,然后您最终会再次出现混淆的名称。

标签: python r pandas dataframe crosstab


【解决方案1】:

unstack怎么样:

df.set_index(['first', 'last', 'class']).unstack() \
  .droplevel(0, axis=1) \
  .rename_axis(None, axis=1) \
  .reset_index()

【讨论】:

    【解决方案2】:

    您可以将NaN 替换为指定的数字,例如-999,使用crosstab 函数,然后将-999 替换为NaN。见下文;

    df1 = df.fillna(-999)
    
    df2 = pd.crosstab(columns=df1['class'], index=[df1["first"],df1["last"]], 
                      values = df1['grade'], aggfunc={max})
    df2[df2 == -999] = np.nan
    
                      max                    
    class         English   Gym History  Math
    first   last                             
    Charles Right    None   NaN    None     3
    John    Smith       1   NaN       1  None
    Mary    Jones    None  None       2  None
    

    【讨论】:

      猜你喜欢
      • 2018-03-26
      • 1970-01-01
      • 1970-01-01
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多