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 |