【问题标题】:Groupby and transpose in pandas, python在熊猫,python中分组和转置
【发布时间】:2018-10-25 09:49:50
【问题描述】:

数据框有

ID  col  col2   col3   col4

1   A    50      S      1
1   A    52      M      4
1   B    45      N      8
1   C    18      S      7

数据框想要

ID  col  colA   colB   colC   colD   colE   colF

1   A    50     52      S      M       1      4
1   B    45     NULL    N     NULL     8     NULL
1   C    18     NULL    S     NULL     7     NULL

我希望每个唯一 ID+col(groupby ID 和 col)各有 1 行。 如果每个 ID+col 有多个条目(最大值可以是 2,不能再多了),则将 col2 的第一个值放入 colA,将第二个值放入 colB,将 col3 的第一个值放入 colC,第二个值放入 colD,放入第一个colE 中 col4 的值和 colF 中的第二个值。如果每个 ID+col 只有一个条目,则 col2 将值放入 colA 和 colB 为 null 等。

我尝试先创建一个计数器:

df['COUNT'] = df.groupby(['ID','col']).cumcount()+1

从这里我想只是添加一个列来说

if count=1 then df['colA']=df.col2
if count=2 then df['colB']=df.col2

.. 但这仍然会产生与原始 df 相同的行数。

【问题讨论】:

    标签: python pandas numpy


    【解决方案1】:

    我认为需要set_indexunstack

    df['COUNT'] = df.groupby(['ID','col']).cumcount()+1
    
    df = df.set_index(['ID','col', 'COUNT'])['col2'].unstack().add_prefix('col').reset_index()
    print (df)
    COUNT  ID col  col1  col2
    0       1   A  50.0  52.0
    1       1   B  45.0   NaN
    2       1   C  18.0   NaN
    

    或者:

    c = df.groupby(['ID','col']).cumcount()+1
    
    df = df.set_index(['ID','col', c])['col2'].unstack().add_prefix('col').reset_index()
    print (df)
       ID col  col1  col2
    0   1   A  50.0  52.0
    1   1   B  45.0   NaN
    2   1   C  18.0   NaN
    

    编辑:

    对于多列的解决方案有点改变,因为在列中使用MultiIndex

    df['COUNT'] = (df.groupby(['ID','col']).cumcount()+1).astype(str)
    
    #remove col2
    df = df.set_index(['ID','col', 'COUNT']).unstack()
    #flatten Multiindex
    df.columns = df.columns.map('_'.join)
    df = df.reset_index()
    print (df)
       ID col  col2_1  col2_2 col3_1 col3_2  col4_1  col4_2
    0   1   A    50.0    52.0      S      M     1.0     4.0
    1   1   B    45.0     NaN      N   None     8.0     NaN
    2   1   C    18.0     NaN      S   None     7.0     NaN
    

    【讨论】:

    • 谢谢,更新了其他用例的问题
    • 完美!字符列中的 None 是否被视为 NULL?
    • 是的,完全正确。在熊猫中也是如此,例如.fillna(0)NoneNaNNaT 一起工作很好
    【解决方案2】:

    您可以将groupbyapply(pd.Series) 一起使用

    df.groupby(['ID','col']).col2.apply(list).apply(pd.Series).add_prefix('col').reset_index()
    Out[404]: 
       ID col  col0  col1
    0   1   A  50.0  52.0
    1   1   B  45.0   NaN
    2   1   C  18.0   NaN
    

    【讨论】:

    • @babz,你可以试试 df.groupby(['ID','col']).agg(tuple),我认为将元组转换为单列没有任何好处
    【解决方案3】:

    不确定这是否是您要寻找的,但它会呈现您正在寻找的相同结果。请注意,我在同一列上使用多个聚合函数,因此使用 ravel 函数来展平数据框列。

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame({'ID':[1,1,1,1], 
                      'Col1':['A','A','B','C'],
                     'Col2':[50,52,45,18]})
    
    df = df.groupby(['ID','Col1']).agg({'Col2':['first','last']})
    df.columns = ["_".join(x) for x in df.columns.ravel()]
    df = df.reset_index()
    df['Col2_last'] = np.where(df.Col2_first == df.Col2_last, float('nan'), df.Col2_last)
    
    print(df)
    

    【讨论】:

      猜你喜欢
      • 2016-11-17
      • 2022-06-22
      • 2019-07-01
      • 2022-12-16
      • 1970-01-01
      • 2018-05-11
      • 2022-01-12
      • 1970-01-01
      • 2017-02-06
      相关资源
      最近更新 更多