我正在尝试计算百分比变化的版本,其中公式为(b-a)/(b+a)
(如果a和b均为0,则应该返回0)
我需要对数据框进行分组,对其进行排序,然后将此功能应用于每个组。
我遇到了与多索引相关的错误。
import random
import pandas as pd
random.seed(42)
group = [random.choice(['a', 'b', 'c', 'd', 'e']) for _ in range(300)]
group2 = [random.choice(['a', 'b', 'c', 'd', 'e']) for _ in range(300)]
x = [random.randint(1, 1000) for _ in range(300)]
number = [random.randint(1, 1000) for _ in range(300)]
df = pd.DataFrame({'group':group, 'group2':group2, 'number':number, 'x':x})
df.sort_values('number').groupby(['group', 'group2'])['x'].groups.keys()
# lets look at a specific group:
df.sort_values('number').groupby(['group', 'group2'])['x'].get_group(('a', 'a'))
206 349
1 226
114 965
48 771
228 662
157 471
128 701
201 500
我需要按两组分组,按数字排序,然后按
(b-a)/(a+b)
我尝试创建一种解决方案,该解决方案很笨拙,当应用于分组的数据框时,它并不能真正起作用。另一件事,我做了pd.concat()
来创建数据帧,因为实际上分组的数据帧具有不同的索引时,索引返回为0+。我这样做是为了保留索引。我知道必须有更好的方法。
def relative_diff(x):
df = pd.concat([x.shift(1), x], axis=1).assign(newcol=np.nan)
for i, a, b in zip(range(len(df)), df.iloc[:,0], df.iloc[:,1]):
if a == 0 and b == 0:
df.iloc[i, 2] = 0
else:
df.iloc[i, 2] = ((b-a)/(b+a))
return df.iloc[:,2]
当我将其应用于特定的群体时,我会得到我真正想要的东西:
example = df.sort_values('number').groupby(['group', 'group2'])['x'].get_group(('a', 'a'))
relative_diff(example)
206 NaN
1 -0.213913
114 0.620487
48 -0.111751
228 -0.076064
157 -0.168579
128 0.196246
201 -0.167361
我现在正在尝试将此功能.apply()
应用于分组的数据框:
df.sort_values('number').groupby(['group', 'group2'])['x'].apply(relative_diff)
我收到cannot handle a non-unique multi-index!
错误,并且被卡住了。
编辑:
查看WeNYoBen的答案后,它对于上述数据集非常适用,但是由于任何原因,当我查看第一组实际数据时,我看到:
144433 11
535075 6
725163 5
211134 3
89080 3
236916 1
593010 1
648680 2
56196 1
404572 2
724103 3
663501 7
它给我错误Buffer has wrong number of dimensions (expected 1, got 0)
答案 0 :(得分:1)
我们可以做到
pd.concat([relative_diff(y) for x , y in df.sort_values('number').groupby(['group', 'group2'])['x']])
答案 1 :(得分:0)
IIUC,您只想先计算位移序列,然后即可执行正常操作:
df = df.sort_values('number')
shifted = df.groupby(['group', 'group2'])['x'].shift()
(shifted - df['x']).div(shifted + df['x']).fillna(0)
输出:
134 0.000000
7 0.050592
103 0.000000
204 0.000000
98 0.000000
...
21 0.055165
229 -0.204819
185 0.372709
263 0.116757
110 -0.161116
Length: 300, dtype: float64