Python 将多行连接为一行

Python 将多行连接为一行,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,从包含一个特定产品的数据框中 data = [['Alpha', '#10','Apple','2020-10-01',4], ['Alpha', '#10','Tomatoes','2020-10-15',1.5], ['Beta', '#12','Banana', '2019-03-06', 2], ['Beta', '#14','Dragonfruit', '2020-04-05', 3], ['Charlie', '#1

从包含一个特定产品的数据框中

data = [['Alpha', '#10','Apple','2020-10-01',4], 
        ['Alpha', '#10','Tomatoes','2020-10-15',1.5], 
        ['Beta', '#12','Banana', '2019-03-06', 2],
        ['Beta', '#14','Dragonfruit', '2020-04-05', 3],
        ['Charlie', '#16','Watermelon', '2019-01-02', 5]]
df = pd.DataFrame(data, columns = ['customer_name', 'order_number','product_variant','date','net_sales'])
我想合并这些行,以便一行包含一个订单号。 预期df

data_expected = [['Alpha', '#10',np.NaN,'Apple','Tomatoes','2020-10-01','2020-10-15',5.5],
                 ['Beta', '#12','#14','Banana','Dragonfruit','2019-03-06','2020-04-05',5], 
                 ['Charlie', '#16',np.NaN,'Watermelon',np.NaN,'2019-01-02',np.NaN,5]]
df_expected = pd.DataFrame(data_expected, columns = ['customer_name','order_number_1', 'order_number_2','product_variant_1','product_variant_2','date_1','date_2','net_sales'])
在实际数据框中,一个客户可能在同一订单号内拥有两个以上的产品, 并且可能有2个以上的订单号,以及2个以上的日期(就像在现实世界中一样)

  • 您可以首先创建一个
    cc
    列,该列接受累计计数
  • 然后,使用
    .groupby
    计算净销售额之和,稍后将其添加到数据框中
  • pivot
    将数据框和多索引列重命名为与
    连接在一起的一列#pivot在以前的版本中有一个主要缺陷。您可以使用pip升级安装pandas--upgrade
  • 通过设置为
    s
    ,创建新的聚合
    net\u sales
    列,该列是您在操作数据框形状之前创建的系列


  • 感谢一个优秀的公认答案的存在,但这里是我的“一行”

    df2 = df.groupby('customer_name').apply(lambda x:pd.DataFrame(x.reset_index().unstack()).transpose())
    df2
    
    给你这个

    |                | ('customer_name', 0)   | ('customer_name', 1)   | ('date', 0)   | ('date', 1)   |   ('index', 0) |   ('index', 1) |   ('net_sales', 0) |   ('net_sales', 1) | ('order_number', 0)   | ('order_number', 1)   | ('product_variant', 0)   | ('product_variant', 1)   |
    |:---------------|:-----------------------|:-----------------------|:--------------|:--------------|---------------:|---------------:|-------------------:|-------------------:|:----------------------|:----------------------|:-------------------------|:-------------------------|
    | ('Alpha', 0)   | Alpha                  | Alpha                  | 2020-10-01    | 2020-10-15    |              0 |              1 |                  4 |                1.5 | #10                   | #10                   | Apple                    | Tomatoes                 |
    | ('Beta', 0)    | Beta                   | Beta                   | 2019-03-06    | 2020-04-05    |              2 |              3 |                  2 |                3   | #12                   | #14                   | Banana                   | Dragonfruit              |
    | ('Charlie', 0) | Charlie                | nan                    | 2019-01-02    | nan           |              4 |            nan |                  5 |              nan   | #16                   | nan                   | Watermelon               | nan                      |
    
    
    这几乎是必需的,除了一些聚合和清理,沿着

    del df2['customer_name']
    del df2['index']
    df2['net_sales_total'] = df2['net_sales'].sum(axis=1)
    del df2['net_sales']
    df2.columns = [c[0] + '_' + str(c[1]) for c in df2.columns]
    df2.rename(columns={'net_sales_total_':'net_sales'}, inplace=True)
    
    所以我们得到了

    |                | date_0     | date_1     | order_number_0   | order_number_1   | product_variant_0   | product_variant_1   |   net_sales |
    |:---------------|:-----------|:-----------|:-----------------|:-----------------|:--------------------|:--------------------|------------:|
    | ('Alpha', 0)   | 2020-10-01 | 2020-10-15 | #10              | #10              | Apple               | Tomatoes            |         5.5 |
    | ('Beta', 0)    | 2019-03-06 | 2020-04-05 | #12              | #14              | Banana              | Dragonfruit         |         5   |
    | ('Charlie', 0) | 2019-01-02 | nan        | #16              | nan              | Watermelon          | nan                 |         5   |
    

    我建议不要连接这些数据。它是表格式的,因此比连接它时更容易操作。您需要如何处理这些客户订单?也许你的问题的解决办法在别的地方。@pawmasz谢谢你的反馈。我想区分客户流失。如果一行属于一个客户,则更容易做到这一点。你不同意吗?你可以把它算作客户流失=(月末不同客户的数量-上月末不同客户的数量)/(上月末不同客户的数量)。稍后,我将使用您的数据框提供一个代码答案。我将赞扬David提供的答案,但出于对他的公平考虑,我们也非常欢迎您提供帮助,尽管不计分。:)这不是我的问题,但这是一个漂亮简洁的答案!:)@桑德凡诺德谢谢你!不幸的是,我得到了一个“ValueError:传递值的形状是(5345,3),索引暗示(1,3)”@Luc您能将pandas升级到最新版本吗
    pivot
    在以前的版本中有一个主要缺陷。您可以使用
    pip安装pandas--升级
    
    
    |                | date_0     | date_1     | order_number_0   | order_number_1   | product_variant_0   | product_variant_1   |   net_sales |
    |:---------------|:-----------|:-----------|:-----------------|:-----------------|:--------------------|:--------------------|------------:|
    | ('Alpha', 0)   | 2020-10-01 | 2020-10-15 | #10              | #10              | Apple               | Tomatoes            |         5.5 |
    | ('Beta', 0)    | 2019-03-06 | 2020-04-05 | #12              | #14              | Banana              | Dragonfruit         |         5   |
    | ('Charlie', 0) | 2019-01-02 | nan        | #16              | nan              | Watermelon          | nan                 |         5   |