在条件上组合Dataframe行

时间:2016-10-24 12:06:55

标签: python pandas

我有一个看起来像的pandas数据框:

INPUT   - 这里是用于创建INPUT的示例可运行代码:

#Create Dataframe with example data
df_example = pd.DataFrame(columns=["START_D","ID_1", "ID_2", "STOP_D"])
df_example["START_D"] = ['2014-06-16', '2014-06-01', '2016-05-01','2014-05-28', '2014-05-20', '2015-09-01']  
df_example['ID_1'] = [1,2,3,2,1,1]
df_example['ID_2'] = ['a', 'a', 'b', 'b', 'a', 'a']
df_example["STOP_D"] = ['2014-07-28', '2014-07-01', '2016-06-01', '2014-08-01', '2014-07-29', '2015-10-01']  

#Convert to datetime
df_example["START_D"] = pd.to_datetime(df_example["START_D"])
df_example["STOP_D"] = pd.to_datetime(df_example["STOP_D"])
df_example

 START_D  ID_1 ID_2     STOP_D
 0 2014-06-16     1    a 2014-07-28
 1 2014-06-01     2    a 2014-07-01
 2 2016-05-01     3    b 2016-06-01
 3 2014-05-28     2    b 2014-08-01
 4 2014-05-20     1    a 2014-07-29
 5 2015-09-01     1    a 2015-10-01

我正在寻找一种按ID_1分组的方法,并合并START_D和STOP_D重叠的行。 start_d将是最小的,stop_d将是最大的。 下面你可以看到我在所有行(iterrows)上循环并在一次检查一个元素时所需的输出。

OUTPUT 即使这种方法有效,我认为它很慢(对于大型DF),我认为必须有更多的pythonic-pandas方法。

>>> df_result
     START_D    ID_1     STOP_D
  0 2014-05-20     1 2014-07-29
  1 2014-05-28     2 2014-08-01
  2 2016-05-01     3 2016-06-01
  3 2015-09-01     1 2015-10-01

谢谢!

2 个答案:

答案 0 :(得分:1)

  • sort_values
  • groupby('ID_1')
  • 跟踪STOP_D.cummax()并查看START_D是否小于之前cummax
  • cumsum生成分组
  • agg抓取min START_Dmax STOP_D
df_example = df.sort_values(['START_D', 'STOP_D'])

def collapse(df):
    s, e = 'START_D', 'STOP_D'
    grps = df[s].gt(df[e].cummax().shift()).cumsum()
    funcs = {s: 'min', e: 'max', 'ID_1': 'first'}
    return df.groupby(grps).agg(funcs)

df_example.groupby('ID_1').apply(collapse).reset_index(drop=True)

enter image description here

答案 1 :(得分:0)

您的问题的难点在于聚合需要导致单个条目。因此,如果START_D和STOP_D不重叠,但ID1相同,则无法进行聚合(即使是自定义)。我建议采取以下步骤:

  1. 遍历每个ID并确保始终发生所需的重叠。这可以通过一些诙谐的编码进行矢量化。如果发现冲突,请生成新ID(使用ID3之类的新列)来解决冲突。否则,如果不存在冲突,只需将ID1放入ID3。
  2. 使用ID3(或您选择的任何名称)进行分组

    df_result = df_example.groupby(['ID1']).agg({START_D: min, STOP_D: max})
    
  3. 性能提升的关键是提出一个矢量化解决方案来检查启动和停止冲突。祝好运!希望这有帮助!