Rah*_*jan 3 python group-by dataframe python-3.x pandas
我有如下所示的数据框
输入
Invoice No Date Text Vendor Days
1000001 1/1/2020 Rent Payment A 0
1000003 2/1/2020 Rent Payment A 1
1000005 4/1/2020 Rent Payment A 2
1000007 6/1/2020 Water payment A 2
1000008 9/2/2020 Rep Payment A 34
1000010 9/2/2020 Car Payment A 0
1000011 10/2/2020 Car Payment A 1
1000012 15/2/2020 Car Payment A 5
1000013 16/2/2020 Car Payment A 1
1000015 17/2/2020 Car Payment A 1
1000002 1/1/2020 Rent Payment B -47
1000004 4/1/2020 Con Payment B 3
1000006 6/1/2020 Con Payment B 2
1000009 9/2/2020 Water payment B 34
1000014 17/2/2020 Test Payment B 8
1000016 19/2/2020 Test Payment B 2
Run Code Online (Sandbox Code Playgroud)
健康)状况
如何编写 python 条件来检查描述、供应商名称和天数列,如果描述、供应商名称相同并且天数 <=2,那么这些行应该在通用组名下分组在一起,比如 (G1) 所有的其他行可以分配一个唯一的组名。所有分组的行都应该有唯一的组名,如输出所示
预期产出
Invoice No Date Text Vendor Days Group
1000001 1/1/2020 Rent Payment A 0 G1
1000003 2/1/2020 Rent Payment A 1 G1
1000005 4/1/2020 Rent Payment A 2 G1
1000007 6/1/2020 Water payment A 2 G2
1000008 9/2/2020 Rep Payment A 34 G3
1000010 9/2/2020 Car Payment A 0 G4
1000011 10/2/2020 Car Payment A 1 G4
1000012 15/2/2020 Car Payment A 5 G5
1000013 16/2/2020 Car Payment A 1 G5
1000015 17/2/2020 Car Payment A 1 G5
1000002 1/1/2020 Rent Payment B -47 G6
1000004 4/1/2020 Con Payment B 3 G7
1000006 6/1/2020 Con Payment B 2 G7
1000009 9/2/2020 Water payment B 34 G8
1000014 17/2/2020 Test Payment B 8 G9
1000016 19/2/2020 Test Payment B 2 G9
Run Code Online (Sandbox Code Playgroud)
您需要groupby在三个项目上使用:'Text'、'Vendor'和 一个布尔表示,表示是否'Days'比单独2定义的组内的变化更多['Text', 'Vendor']。
之后,您需要命名唯一的组。我在下面提供了两种方法。
ngroupf = lambda x: x.diff().fillna(0).gt(2).cumsum()
d = df.groupby(['Text', 'Vendor']).Days.transform(f)
g = df.groupby(['Text', 'Vendor', d], sort=False).ngroup()
df.assign(Group=g.add(1).astype(str).radd('G'))
Invoice No Date Text Vendor Days Group
0 1000001 1/1/2020 Rent Payment A 0 G1
1 1000003 2/1/2020 Rent Payment A 1 G1
2 1000005 4/1/2020 Rent Payment A 2 G1
3 1000007 6/1/2020 Water payment A 2 G2
4 1000008 9/2/2020 Rep Payment A 34 G3
5 1000010 9/2/2020 Car Payment A 0 G4
6 1000011 10/2/2020 Car Payment A 1 G4
7 1000012 15/2/2020 Car Payment A 5 G5
8 1000013 16/2/2020 Car Payment A 1 G5
9 1000015 17/2/2020 Car Payment A 1 G5
10 1000002 1/1/2020 Rent Payment B -47 G6
11 1000004 4/1/2020 Con Payment B 3 G7
12 1000006 6/1/2020 Con Payment B 2 G7
13 1000009 9/2/2020 Water payment B 34 G8
14 1000014 17/2/2020 Test Payment B 8 G9
15 1000016 19/2/2020 Test Payment B 2 G9
Run Code Online (Sandbox Code Playgroud)
factorizef = lambda x: x.diff().fillna(0).gt(2).cumsum()
d = df.groupby(['Text', 'Vendor']).Days.transform(f)
g = pd.factorize([*zip(df.Text, df.Vendor, d)])[0]
df.assign(Group=[f'G{i + 1}' for i in g])
Invoice No Date Text Vendor Days Group
0 1000001 1/1/2020 Rent Payment A 0 G1
1 1000003 2/1/2020 Rent Payment A 1 G1
2 1000005 4/1/2020 Rent Payment A 2 G1
3 1000007 6/1/2020 Water payment A 2 G2
4 1000008 9/2/2020 Rep Payment A 34 G3
5 1000010 9/2/2020 Car Payment A 0 G4
6 1000011 10/2/2020 Car Payment A 1 G4
7 1000012 15/2/2020 Car Payment A 5 G5
8 1000013 16/2/2020 Car Payment A 1 G5
9 1000015 17/2/2020 Car Payment A 1 G5
10 1000002 1/1/2020 Rent Payment B -47 G6
11 1000004 4/1/2020 Con Payment B 3 G7
12 1000006 6/1/2020 Con Payment B 2 G7
13 1000009 9/2/2020 Water payment B 34 G8
14 1000014 17/2/2020 Test Payment B 8 G9
15 1000016 19/2/2020 Test Payment B 2 G9
Run Code Online (Sandbox Code Playgroud)
# The first element of group Cumulatively summing True/False
# will get NaN so we fill it will create a new value every time
# in with 0 ? we see a True. This creates groups
# ? ?
# adjacent differences Should be obvious
# ?????? ????????? ????? ????????
f = lambda x: x.diff().fillna(0).gt(2).cumsum()
Run Code Online (Sandbox Code Playgroud)