【问题标题】:Merge rows with the same date and id and append to the right side合并具有相同日期和 id 的行并附加到右侧
【发布时间】:2020-12-30 20:15:17
【问题描述】:

我想合并具有相同日期和 empIdn 的行 来自这个数据框:

,empIdn,date,time_0,time_1,time_2,time_3,time_4
0,191206,2020-12-02,07:22:50,12:15:21,12:15:23,12:35:35
1,191206,2020-12-02,17:27:46,17:27:49,,

我想这样实现:

,empIdn,date,time_0,time_1,time_2,time_3,time_4,time_5,time_6
0,191206,2020-12-02,07:22:50,12:15:21,12:15:23,12:35:35,17:27:46,17:27:49

我想就如何做到这一点寻求一些帮助,到目前为止我做了什么:

df1 = pd.read_csv("1.csv",index_col=[0])
df2 = pd.read_csv("2.csv",index_col=[0])

final_df = pd.concat([df1, df2], sort = True)
final_df.groupby(['date', 'empIdn']).agg(lambda x: x.tolist())

final_df.to_csv("fff.csv")

我是熊猫新手。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    你需要先melt你的数据框,按当前的indexempIdndate排序。

    然后使用groupby.cumcount() 方法根据上述顺序创建一个新的time_ 计数器。

    最后一步是创建一个新的index,然后是unstack

    让我们在您的示例中添加几条记录,看看非受骗者会发生什么。

    我们预期输出之间的主要区别在于,我将time_4 删除为第一行,因为它是NA,如果这不是预期的行为,那么您可以首先fillna 在重复行的第一个值上使用任意值。

    类似df = df.fillna(df[df.duplicated(subset=['empIdn','date'],keep='last')].fillna(-1))

    print(df)
    
       empIdn       date    time_0    time_1    time_2    time_3  time_4
    0  191206 2020-12-02  07:22:50  12:15:21  12:15:23  12:35:35     NaN
    1  191206 2020-12-02  17:27:46  17:27:49       NaN       NaN     NaN
    2  191207 2020-12-02  07:22:50  12:15:21  12:15:23  12:35:35     NaN
    3  191207 2020-11-02  07:22:50  12:15:21  12:15:23  12:35:35     NaN
    4  191207 2020-12-02  17:27:46  17:27:49       NaN       NaN     NaN
    

    根据上面的示例,我们可以预期输出三行,其中 empIdn 191206 和 191207 按日期重复,192017 不重复,因为它不是重复的。


    df1 = (
        pd.melt(df.reset_index(), id_vars=["empIdn", "date", "index"], var_name="time")
        .dropna(subset=["value"]) ## we don't care about nulls here.
        .sort_values(["empIdn", "date", "index"])
    )
    
    df1['time'] = 'time_' + df1.assign(key=df1.groupby(['empIdn','date']).cumcount()).astype(str)['key']
    
    final = df1.set_index(["empIdn", "date", "time"]).drop("index", 1).unstack("time").droplevel(
        0, 1
    ).reset_index()
    
    print(final)
    


    -1 作为填充值。

    开箱cumcount

    从下面您可以清楚地看到 key 何时递增以创建我们的新 key 列 -

    这里的关键是 order 通过你的原始索引和 groupby empIdndate

    print(df1.assign(key=df1.groupby(['empIdn','date']).cumcount()))
        empIdn        date index    time     value key
    0   191206  2020-12-02     0  time_0  07:22:50   0
    5   191206  2020-12-02     0  time_1  12:15:21   1
    10  191206  2020-12-02     0  time_2  12:15:23   2
    15  191206  2020-12-02     0  time_3  12:35:35   3
    1   191206  2020-12-02     1  time_0  17:27:46   4 # < -- new row in original dataframe.
    6   191206  2020-12-02     1  time_1  17:27:49   5 # < -- we want to increment these to time_4 / time_5
    3   191207  2020-11-02     3  time_0  07:22:50   0
    8   191207  2020-11-02     3  time_1  12:15:21   1
    13  191207  2020-11-02     3  time_2  12:15:23   2
    18  191207  2020-11-02     3  time_3  12:35:35   3
    2   191207  2020-12-02     2  time_0  07:22:50   0
    7   191207  2020-12-02     2  time_1  12:15:21   1
    12  191207  2020-12-02     2  time_2  12:15:23   2
    17  191207  2020-12-02     2  time_3  12:35:35   3
    4   191207  2020-12-02     4  time_0  17:27:46   4
    9   191207  2020-12-02     4  time_1  17:27:49   5
    

    【讨论】:

    • @CarlojuneCaimen 运营数据很难管理,但一旦掌握了窍门,您就会飞起来。祝您分析顺利,希望步骤清晰。如果您需要更多帮助,请随时提出新问题。
    • 我只是很好奇这行 df1['time'] = 'time_' + df1.assign(key=df1.groupby(['empIdn','date']).cumcount ()).astype(str)['key'] final = df1.set_index(["empIdn", "date", "time"]).drop("index", 1).unstack("time"). droplevel( 0, 1 ).reset_index()
    • @CarlojuneCaimen 自己运行df1.assign(key=df1.groupby(['empIdn','date']).cumcount()).astype(str),您就会明白。后者只是在旋转列之前设置索引,它是在 pandas 中旋转的众多方法之一,我更喜欢它,但其他人更喜欢使用 pd.crosstabpd.pivot
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2013-07-31
    • 2023-03-08
    • 2020-12-23
    相关资源
    最近更新 更多