【问题标题】:pandas pivot table - rearrange熊猫数据透视表 - 重新排列
【发布时间】:2016-05-24 21:52:45
【问题描述】:

我有一个带有一些列的熊猫数据框。我想以不同的方式重新排列它们。下面是一个例子:

time,name,feature,value
33 20 May 2016 14:00:00 -0700,John,badL,2
45 19 May 2016 18:00:00 -0700,John,badL,1
120 17 May 2016 11:00:00 -0700,John,badL,1
220 20 May 2016 14:00:00 -0700,John,totalL,20
450 19 May 2016 18:00:00 -0700,John,totalL,15
330 18 May 2016 15:00:00 -0700,Mary,badL,2
330 18 May 2016 15:00:00 -0700,Mary,totalL,20
550 21 May 2016 12:00:00 -0700,Mary,adCmd,4
700 22 May 2016 16:00:00 -0700,Mary,PC,3
800 22 May 2016 16:00:00 -0700,Mary,eCon,200

注意:第一列值(时间)前面是索引值(33、45,120、...)。 从上面的数据框中,我希望得到的数据框为:

time,name,badL,totalL,adCmd,PC,eCon
20 May 2016 14:00:00 -0700,John,2,20,0,0,0
19 May 2016 18:00:00 -0700,John,1,15,0,0,0
17 May 2016 11:00:00 -0700,John,1,0,0,0,0
18 May 2016 15:00:00 -0700,Mary,2,20,0,0,0
21 May 2016 12:00:00 -0700,Mary,0,0,4,0,0
22 May 2016 16:00:00 -0700,Mary,0,0,0,3,200

注意:5 月 17 日,John 没有任何总计 L。所以,用 0 填充它。

有没有一种优雅的方法来做到这一点?我将时间字段设置为 pd.to_datetime,然后,比较...看起来很乏味。对于上面的例子,我只有两个“特征”(badL,totalL)。以后我还会有几个。

这就是我所拥有的 - 但是,它为第二个功能添加了不同的行......(totalL)......而不是将其放在同一行中。

for f in ['badL', 'totalL']:
    dff = df[df.feature == f]
    print dff
    if len(dff.index) > 0:
        fullFeatureDf[f] = dff.feature_value

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    设置

    from StringIO import StringIO
    import pandas as pd
    
    text = '''time,name,f1,value
    20 May 2016 14:00:00 -0700,John,badL,2
    19 May 2016 18:00:00 -0700,John,badL,1
    17 May 2016 11:00:00 -0700,John,badL,1
    20 May 2016 14:00:00 -0700,John,totalL,20
    19 May 2016 18:00:00 -0700,John,totalL,15
    17 May 2016 11:00:00 -0700,John,totalL,12
    '''
    
    df = pd.read_csv(StringIO(text))
    
    print df
    
                             time  name      f1  value
    0  20 May 2016 14:00:00 -0700  John    badL      2
    1  19 May 2016 18:00:00 -0700  John    badL      1
    2  17 May 2016 11:00:00 -0700  John    badL      1
    3  20 May 2016 14:00:00 -0700  John  totalL     20
    4  19 May 2016 18:00:00 -0700  John  totalL     15
    5  17 May 2016 11:00:00 -0700  John  totalL     12
    

    使用unstack的解决方案

    df = df.set_index(['time', 'name', 'f1'])
    
    print df
    
                                            value
    time                       name f1           
    20 May 2016 14:00:00 -0700 John badL        2
    19 May 2016 18:00:00 -0700 John badL        1
    17 May 2016 11:00:00 -0700 John badL        1
    20 May 2016 14:00:00 -0700 John totalL     20
    19 May 2016 18:00:00 -0700 John totalL     15
    17 May 2016 11:00:00 -0700 John totalL     12
    

    然后取消堆叠以执行枢轴。它获取行索引的一部分并将其移动为列。

    print df.unstack()
    
                                    value       
    f1                               badL totalL
    time                       name             
    17 May 2016 11:00:00 -0700 John     1     12
    19 May 2016 18:00:00 -0700 John     1     15
    20 May 2016 14:00:00 -0700 John     2     20
    

    在精神上,这与 Yakym Pirozhenko 的解决方案相同。只是一种稍微不同的方式。这对我来说更直观,但对你来说可能不是。

    【讨论】:

    • 更新了问题..带有输入和所需的输出。
    【解决方案2】:

    这是df.pivot的工作:

    import pandas as pd
    from io import StringIO
    
    df = pd.read_csv(StringIO(
    '''
    time,name,feature,value
    33 20 May 2016 14:00:00 -0700,John,badL,2
    45 19 May 2016 18:00:00 -0700,John,badL,1
    120 17 May 2016 11:00:00 -0700,John,badL,1
    220 20 May 2016 14:00:00 -0700,John,totalL,20
    450 19 May 2016 18:00:00 -0700,John,totalL,15
    330 18 May 2016 15:00:00 -0700,Mary,badL,2
    330 18 May 2016 15:00:00 -0700,Mary,totalL,20
    550 21 May 2016 12:00:00 -0700,Mary,adCmd,4
    700 22 May 2016 16:00:00 -0700,Mary,PC,3
    800 22 May 2016 16:00:00 -0700,Mary,eCon,200
    '''), sep=',').set_index(['time', 'name'])
    
    df_new = df.pivot(columns='feature').fillna(0).astype(int)
    
    #                                     value
    # feature                                PC adCmd badL eCon totalL
    # time                           name
    # 120 17 May 2016 11:00:00 -0700 John     0     0    1    0      0
    # 220 20 May 2016 14:00:00 -0700 John     0     0    0    0     20
    # 33 20 May 2016 14:00:00 -0700  John     0     0    2    0      0
    # 330 18 May 2016 15:00:00 -0700 Mary     0     0    2    0     20
    # 45 19 May 2016 18:00:00 -0700  John     0     0    1    0      0
    # 450 19 May 2016 18:00:00 -0700 John     0     0    0    0     15
    # 550 21 May 2016 12:00:00 -0700 Mary     0     4    0    0      0
    # 700 22 May 2016 16:00:00 -0700 Mary     3     0    0    0      0
    # 800 22 May 2016 16:00:00 -0700 Mary     0     0    0  200      0
    

    【讨论】:

    • 有趣。我不知道数据框中的这个枢轴函数。感谢您向我介绍这一点。正如我所说,我有更多的功能(f1、f2、f3...、f10)。一个例子:对于用户 John,我可能只有 6 个特征,但是,在输出数据框 (df_new) 中,我希望所有 10 个特征作为列,并用值填充适当的列,其余的用零填充。你是怎么做到的?
    • 更新了问题..带有输入和所需的输出。
    • 我认为 pd.pivot_table(df, index = [list of features], fill_value = 0) 可能会完成这项工作....
    • 您能提供一个具有更多功能的具体示例吗?填写nans 可以使用df.fillna(0) 独立完成。
    • 行得通!我对 Pandas 了解得越多,我就越吃惊。非常感谢 Yakym!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 2021-02-28
    • 2023-01-11
    • 2022-08-03
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多