【问题标题】:Pandas groupby changes return type when reassembling groupsPandas groupby 在重新组装组时更改返回类型
【发布时间】:2017-01-07 23:11:55
【问题描述】:

我有一个数据框:

df = pd.DataFrame({'c':[0,1,1,2,2,2],   'date':pd.to_datetime(['2016-01-01','2016-02-01','2016-03-01','2016-04-01','2016-05-01','2016-06-01'])})

对于每一行,我想得到一个数字 = 每个日期的月份数(Jan=1,Feb=2 等)+ 该组的长度(第一组有 1 个成员,第二组有 2 个等。 ):

所以它应该返回如下内容:

c       date   num
0 2016-01-01    2
1 2016-02-01    4
1 2016-03-01    5
2 2016-04-01    7
2 2016-05-01    8
2 2016-06-01    9

我创建了一个函数:

def testlambda(x):
    print(x)
    return x.dt.month.astype('int') + len(x)

并使用了groupby + transform:

df['num'] = df.groupby(['c'])['date'].transform(lambda x: testlambda(x))

但返回的新列仍然是日期格式,即使我的 lambda 返回 int。

在这里做什么?

【问题讨论】:

    标签: python pandas group-by


    【解决方案1】:

    尝试使用DataFrameGroupBy.transform() 而不是SeriesGroupBy.transform(),因为后者会尝试将结果转换为源数据类型:

    In [131]: def testlambda(x):
         ...:     #print(x)
         ...:     return x.dt.month.astype('int') + len(x)
         ...:
    
    In [132]: df
    Out[132]:
       c       date
    0  0 2016-01-01
    1  1 2016-02-01
    2  1 2016-03-01
    3  2 2016-04-01
    4  2 2016-05-01
    5  2 2016-06-01
    
    #                                      v        v - thats's the only difference    
    In [133]: df['num'] = df.groupby(['c'])[['date']].transform(lambda x: testlambda(x))
    
    In [134]: df
    Out[134]:
       c       date  num
    0  0 2016-01-01    2
    1  1 2016-02-01    4
    2  1 2016-03-01    5
    3  2 2016-04-01    7
    4  2 2016-05-01    8
    5  2 2016-06-01    9
    

    【讨论】:

    • 你就是男人!你能更新答案以使用 lambda 吗?真正的函数比单行函数更复杂,所以我认为调用函数是一种更通用的解决方案。但这太棒了。
    • 我不知道DataFrameGroupBy.transform()SeriesGroupBy.transform() 之间有区别。这在某处有记录吗?系列版本的行为正是我对here感到好奇的地方。
    • @iwbabn,当然,我已经编辑了我的答案 - 我使用了你的 testlambda() 函数
    • @3novak,我不知道它是否记录在案 - 这是我观察的结果......
    • 谢谢,@MaxU。您是否介意放弃对this thread 的回复,指出您对行为差异的观察?
    【解决方案2】:

    我会通过在transform 中使用size 来避免lambda

    df.assign(num=df.groupby('c').c.transform('size') + df.date.dt.month)
    
       c       date  num
    0  0 2016-01-01    2
    1  1 2016-02-01    4
    2  1 2016-03-01    5
    3  2 2016-04-01    7
    4  2 2016-05-01    8
    5  2 2016-06-01    9
    

    【讨论】:

      猜你喜欢
      • 2012-10-16
      • 2019-11-30
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      • 2018-08-06
      • 1970-01-01
      • 2016-12-23
      • 1970-01-01
      相关资源
      最近更新 更多