我正在尝试使用以下格式在数据框中实现新列:
Client_id Product_a
1 1
1 2
1 1
1 0
2 1
2 0
2 3
2 1
所以...我想要做的是三个新列(total_buy,total_sell和total_operations)。在这些新列中,我想计算每个client_id的购买,销售总额和操作总数。每个client_id在表中至少出现一次,最多出现24次。 所以我的输出应该是这样的(对于上面显示的样本):
Client_id A_buy A_sell A_operations
1 2 2 4
2 4 3 7
我使用的是具有不同功能的groupby作为sum / mean / min / max,它们非常有用,但现在我想尝试这种新方法。实际上我有大约52k客户和12种不同的产品,但我无法实现如何处理这项新任务。 我的数据框中的总行数约为600k,每个客户端至少出现1次,最多24次(我有2年的数据)
有任何内置函数可以完成此任务吗? 有任何建议可以解决这个问题吗?
感谢您提供建议方面的帮助!
答案 0 :(得分:2)
让我们尝试这样的事情:
df = pd.DataFrame({'Client_id':[1,1,1,1,2,2,2,2],'Product_a':[1,2,1,0,1,0,3,1]})
#Define action based on diff previous record fill first record with first value in group
df_out = df.assign(action=df.groupby('Client_id')['Product_a']\
.apply(lambda x: x.diff().fillna(x.iloc[0])))
#Classify buy or sell based of positive or negative action
df_out['buys'] = np.where(df_out.action.gt(0), df_out.action, 0)
df_out['sells'] = np.where(df_out.action.lt(0), df_out.action.mul(-1), 0)
#Lastly, groupby and sum records by client
df_out.groupby('Client_id')[['buys', 'sells']].sum().eval('operations = buys + sells')\
.add_prefix('A_').reset_index()
输出:
Client_id A_buys A_sells A_operations
0 1 2.0 2.0 4.0
1 2 4.0 3.0 7.0
答案 1 :(得分:0)
我的pandas代码使用一些简单的过滤器,并为我的数据库中的所有产品进行序列化...如果有人只需要在简单的列上使用它,则不需要for循环只需更改str(产品)列名。
for product in productos:
dfloop[str(product) + '_buys'] = dfloop[product]
dfloop[str(product) + '_sells'] = 0
dfloop.loc[dfloop["id_cliente"] == dfloop["id_cliente"].shift(1),[str(product) + '_buys']] \
= dfloop[product] - dfloop[product].shift(1)
dfloop.loc[dfloop[str(product) + '_buys'] < 0 ,[str(product) + '_sells']] = -dfloop[str(product) + '_buys']
dfloop.loc[dfloop[str(product) + '_buys'] < 0 ,[str(product) + '_buys']] = 0
代码非常简单,首先我在我的数据库中为每个产品制作新的买卖列然后我使用pandas中的shift函数...首先检查是否有id更改然后休息行之间的产品差异。
最后两行代码只是正确地重新计算了买卖的总和。它适用于任何数据库只有很少的变化.. 我希望这段代码将来会帮助某人。