【问题标题】:Groupby on two column and applying transform(Partition), rolling and concatenation on particular column using pandas - PythonGroupby 在两列上并使用 pandas 在特定列上应用变换(分区)、滚动和连接 - Python
【发布时间】:2019-11-22 05:20:21
【问题描述】:

我有带有列的 DataFrame(句点、spn、cpt、付款人)。我必须仅连接 2 个周期的列(付款人)值(仅滚动两个月)。 DF样本:

period     spn  cpt payer
7/1/2018    a   23  UNITED, HEALTH
7/1/2018    a   24  CARE, MEDI
7/1/2018    b   23  ASSIGN
8/1/2018    a   23  ASSIGN
8/1/2018    a   24  CARE, MEDI
8/1/2018    b   23  ASSIGN, MEDI
9/1/2018    a   23  ASSIGN
9/1/2018    a   24  MEDI
9/1/2018    b   23  ASSIGN, MEDI

我尝试过: df.groupby(['spn', 'cpt'])['payer'].transform(lambda x: x.rolling(2, min_periods = 1).apply(', '.join, raw=False))

我收到一个错误:无法处理此类型 -> 对象。

因此将列(付款人)转换为字符串类型并尝试使用与上述相同的代码。但我得到了同样的错误。请帮我解决这个问题。

预期结果

period    spn   cpt  payer             payer_concate
7/1/2018    a   23   UNITED, HEALTH    UNITED, HEALTH, ASSIGN
7/1/2018    a   24   CARE, MEDI        CARE, MEDI, CARE, MEDI
7/1/2018    b   23   ASSIGN            ASSIGN, ASSIGN, MEDI
8/1/2018    a   23   ASSIGN            ASSIGN, ASSIGN
8/1/2018    a   24   CARE, MEDI        CARE, MEDI, MEDI
8/1/2018    b   23   ASSIGN, MEDI      ASSIGN, MEDI, ASSIGN, MEDI
9/1/2018    a   23   ASSIGN            ASSIGN
9/1/2018    a   24   MEDI              MEDI
9/1/2018    b   23   ASSIGN, MEDI      ASSIGN, MEDI

提前致谢

【问题讨论】:

  • 不分享截图,你能分享一些我们可以复制的东西吗?至少使用print() 分享,以便我们复制粘贴并解决您的问题
  • 感谢您的浏览。我已经用值替换了图像(可以复制和工作)。

标签: python pandas datetime pandas-groupby string-concatenation


【解决方案1】:

首先按句点对值进行排序。然后使用 groupby 并转换和连接相邻的付款人。因为上一期没有关注者,所以这个值是None,所以用combine_first填满df的原始值。

s = df.sort_values('period').groupby(['spn','cpt']).payer\
                       .transform(lambda x: x +',' + x.shift(-1)).combine_first(df.payer)
df["payer_concatenate"] = s

结果

    period      spn cpt payer           payer_concatenate
0   7/1/2018    a   23  UNITED,HEALTH   UNITED,HEALTH,ASSIGN
1   7/1/2018    a   24  CARE,MEDI       CARE,MEDI,CARE,MEDI
2   7/1/2018    b   23  ASSIGN          ASSIGN,ASSIGN,MEDI
3   8/1/2018    a   23  ASSIGN          ASSIGN,ASSIGN
4   8/1/2018    a   24  CARE,MEDI       CARE,MEDI,MEDI
5   8/1/2018    b   23  ASSIGN,MEDI     ASSIGN,MEDI,ASSIGN,MEDI
6   9/1/2018    a   23  ASSIGN          ASSIGN
7   9/1/2018    a   24  MEDI            MEDI
8   9/1/2018    b   23  ASSIGN,MEDI     ASSIGN,MEDI

【讨论】:

  • 谢谢@pythonic833 @Gunnvant。我努力通过这段代码得到我的答案:df.sort_values(by = 'period', ascending = False, inplace = True)。 df['payer_concate'] = pd.concat([df.groupby(['spn', 'cpt'])['payer'].shift(i) for i in range(2)], axis=1).fillna('').T.apply(lambda x: ', '.join(x)) 。这比@pythonic833 的代码快。感谢你们宝贵的时间和代码
【解决方案2】:

应该这样做:

import pandas as pd
import numpy as np
data=pd.DataFrame({'period':['7/1/2018','7/1/2018','7/1/2018','8/1/2018','8/1/2018','8/1/2018','9/1/2018','9/1/2018','9/1/2018'],'span':['a','a','b','a','a','b','a','a','b'],'cpt':[23,24,23,23,24,23,23,24,23],'payer':['UNITED, HEALTH','CARE, MEDI','ASSIGN','ASSIGN','CARE, MEDI','ASSIGN, MEDI','ASSIGN','MEDI','ASSIGN, MEDI']})
Groups=[data.groupby(['span','cpt']).groups[a] for a in data.groupby(['span','cpt']).groups]
for grp in Groups:
    data.loc[grp,'payer_1']=(data.iloc[grp]['payer'].shift(-1)).values

def get_cols(row):
    if row['payer_1'] is np.nan:
        return row['payer']
    else:
        return row['payer']+", "+row['payer_1']
data['final']=data.apply(get_cols,axis=1)

数据

         period span  cpt           payer       payer_1                       final
0  7/1/2018    a   23  UNITED, HEALTH        ASSIGN      UNITED, HEALTH, ASSIGN
1  7/1/2018    a   24      CARE, MEDI    CARE, MEDI      CARE, MEDI, CARE, MEDI
2  7/1/2018    b   23          ASSIGN  ASSIGN, MEDI        ASSIGN, ASSIGN, MEDI
3  8/1/2018    a   23          ASSIGN        ASSIGN              ASSIGN, ASSIGN
4  8/1/2018    a   24      CARE, MEDI          MEDI            CARE, MEDI, MEDI
5  8/1/2018    b   23    ASSIGN, MEDI  ASSIGN, MEDI  ASSIGN, MEDI, ASSIGN, MEDI
6  9/1/2018    a   23          ASSIGN           NaN                      ASSIGN
7  9/1/2018    a   24            MEDI           NaN                        MEDI
8  9/1/2018    b   23    ASSIGN, MEDI           NaN                ASSIGN, MEDI

问候 Gunnvant,Jigsaw

【讨论】:

  • Pandas rolling() 不支持除少数数值聚合函数之外的任何东西,例如 mean()、min() 等。我也尝试了滚动,然后是 apply() 方法,但我认为完成 rolling() 操作后,您不能在 apply() 中传递任何任意函数。
  • 是的,在这种情况下,移位是更好的选择,因为我们只想有两个连接。但是滚动也应该起作用.rolling(2).apply(lambda x: x[0] + x[1]) 可能会起作用。
  • 好的,我查过了。似乎滚动只能处理数字而不是字符串。但是问题仍然可以像您一样解决,或者有一种方法可以使用groupby
  • 看到你的方法,我认为你的方法更像熊猫
【解决方案3】:

我可以回答你的部分问题:

data['period']=pd.to_datetime(data.period)
data['month']= data.period.dt.month
data.set_index(['spn', 'cpt','period'], inplace=True)
df = data.groupby(['spn', 'cpt']).agg(','.join)
df = data.merge(df, on=['spn','cpt'])
df.rename({'payer_x':'payer','payer_y':'payer_concate'})

输出:

spn cpt           payer  month                     payer_concate

a   23   UNITED, HEALTH      7      UNITED, HEALTH,ASSIGN,ASSIGN
    23           ASSIGN      8      UNITED, HEALTH,ASSIGN,ASSIGN
    23           ASSIGN      9      UNITED, HEALTH,ASSIGN,ASSIGN
    24       CARE, MEDI      7        CARE, MEDI,CARE, MEDI,MEDI
    24       CARE, MEDI      8        CARE, MEDI,CARE, MEDI,MEDI
    24             MEDI      9        CARE, MEDI,CARE, MEDI,MEDI
b   23           ASSIGN      7  ASSIGN,ASSIGN, MEDI,ASSIGN, MEDI
    23     ASSIGN, MEDI      8  ASSIGN,ASSIGN, MEDI,ASSIGN, MEDI
    23     ASSIGN, MEDI      9  ASSIGN,ASSIGN, MEDI,ASSIGN, MEDI

【讨论】:

  • 感谢您的回复。请检查您的结果是否与我要查找的结果不符。申请groupby后,需要滚两个月。但是您已将所有值(所有月份)用于聚合
  • 请告诉我。如果你有时间调查一下。
  • 嗨@RaghavendraS,我可以回答你问题的第一部分。一旦我弄清楚该怎么做,我很乐意与您分享
猜你喜欢
  • 1970-01-01
  • 2018-12-26
  • 2019-01-29
  • 1970-01-01
  • 2021-12-13
  • 2023-01-17
  • 2018-04-21
  • 2022-06-16
  • 1970-01-01
相关资源
最近更新 更多