Python 使用不带groupby Split Apply Combine的分类键对数据帧中的值进行排序
所以。。。我有一个数据框,看起来像这样,但要大得多:Python 使用不带groupby Split Apply Combine的分类键对数据帧中的值进行排序,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,所以。。。我有一个数据框,看起来像这样,但要大得多: DATE ITEM STORE STOCK 0 2018-06-06 A L001 4 1 2018-06-06 A L002 0 2 2018-06-06 A L003 4 3 2018-06-06 B L001 1 4 2018-06-06 B L002 2 您可以使用以下代码复制相同的
DATE ITEM STORE STOCK
0 2018-06-06 A L001 4
1 2018-06-06 A L002 0
2 2018-06-06 A L003 4
3 2018-06-06 B L001 1
4 2018-06-06 B L002 2
您可以使用以下代码复制相同的数据帧:
import pandas as pd
import numpy as np
import itertools as it
lojas = ['L001', 'L002', 'L003']
itens = list("ABC")
dr = pd.date_range(start='2018-06-06', end='2018-06-12')
df = pd.DataFrame(data=list(it.product(dr, itens, lojas)), columns=['DATE', 'ITEM', 'STORE'])
df['STOCK'] = np.random.randint(0,5, size=len(df.ITEM))
gg = df.groupby([df.ITEM, df.STORE])
lg = []
for (name, group) in gg:
aux = group.copy()
aux.reset_index(drop=True, inplace=True)
aux['DELTA'] = aux.STOCK.diff().fillna(value=0, inplace=Tr
lg.append(aux)
df = pd.concat(lg)
我想计算每对ITEM-STORE中天数之间的去库存差异,使用函数在groupby对象中迭代组很容易。diff可以得到如下结果:
DATE ITEM STORE STOCK DELTA
0 2018-06-06 A L001 4 NaN
9 2018-06-07 A L001 0 -4.0
18 2018-06-08 A L001 4 4.0
27 2018-06-09 A L001 0 -4.0
36 2018-06-10 A L001 3 3.0
45 2018-06-11 A L001 2 -1.0
54 2018-06-12 A L001 2 0.0
我已经通过以下代码实现了这一点:
import pandas as pd
import numpy as np
import itertools as it
lojas = ['L001', 'L002', 'L003']
itens = list("ABC")
dr = pd.date_range(start='2018-06-06', end='2018-06-12')
df = pd.DataFrame(data=list(it.product(dr, itens, lojas)), columns=['DATE', 'ITEM', 'STORE'])
df['STOCK'] = np.random.randint(0,5, size=len(df.ITEM))
gg = df.groupby([df.ITEM, df.STORE])
lg = []
for (name, group) in gg:
aux = group.copy()
aux.reset_index(drop=True, inplace=True)
aux['DELTA'] = aux.STOCK.diff().fillna(value=0, inplace=Tr
lg.append(aux)
df = pd.concat(lg)
但在一个大数据帧中,它变得不切实际。有没有更快捷的python方法来完成此任务?我已经尝试改进您的groupby代码,因此这应该会快得多
v = df.groupby(['ITEM', 'STORE'], sort=False).STOCK.diff()
df['DELTA'] = np.where(np.isnan(v), 0, v)
这里有一些建议/想法:
不要迭代组
如果序列属于同一数据帧,则不要将序列作为分组传递。而是传递字符串标签。
差异可以矢量化
最后一行相当于fillna,但fillna比np慢
指定sort=False将防止输出按分组键排序,从而进一步提高性能
这也可以重写为
df['DELTA'] = df.groupby(['ITEM', 'STORE'], sort=False).STOCK.diff().fillna(0)
你能想出一个更好的办法吗?输入和输出是不同的。两个显示的帧都是精确的。下一次我提供的代码的开头,为随机生成器播种是个好主意。首先,输入的thks。这是非常有用的。第二:如果您使用的是带有可编辑窗口的“滚动”,而不是diff,那么如何避免对GROUP进行迭代。例如:窗口值包含在一个collumns?@RodrigoTeixeira 1中。没问题。如果使用自定义函数,则无法避免迭代,抱歉。如果此答案解决了您的问题,请将其标记为已接受。如果您还有其他后续问题,请提出新问题。