生成对数据框进行分组的新列

时间:2017-11-22 13:30:42

标签: python pandas numpy spyder

我正在尝试使用以下格式在数据框中实现新列:

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年的数据)

有任何内置函数可以完成此任务吗? 有任何建议可以解决这个问题吗?

感谢您提供建议方面的帮助!

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更改然后休息行之间的产品差异。

最后两行代码只是正确地重新计算了买卖的总和。它适用于任何数据库只有很少的变化.. 我希望这段代码将来会帮助某人。