我正在尝试从同一数据帧中的每隔一行中减去每一行。我见过this。但是那里的代码不适用于多索引。
这是我拥有的数据框的结构
a c z
index name
0 foo 15 8 0
bar 4 1 0
baz 7 2 0
toto 12 3 0
titi 5 0 0
1 foo 8 6 0
bar 4 1 0
baz 6 3 0
toto 5 1 0
titi 6 0 0
我想要的结构如下:
index name1 name2 a c z
0 foo bar 11 7 0
foo baz 8 6 0
bar baz -3 -1 0
我已经尝试了2件事。第一个不保留name1
,name2
,并且在链接中基本上是相同的解决方案。
第二种方法可以工作,但是要花几个小时才能计算:
def df_diff(newticker: pd.DataFrame):
times = newticker.index.get_level_values("index")
timesu = times.unique()
symbols = newticker.index.get_level_values("name")
symbolsu = symbols.unique()
symb_combination = list(itertools.permutations(symbolsu, 2))
tuple_list = []
#
for timet in timesu:
for sym in symb_combination:
tuple_list.append((timet, sym[0], sym[1]))
#
mindex = pd.MultiIndex.from_tuples(tuple_list,
names=["index", "name1", "name2"])
cols = newticker.columns
#
dfdiff = pd.DataFrame(columns=cols,
index=mindex)
#
for symt in symb_combination:
sym1 = symt[0]
sym2 = symt[1]
sym1df = newticker.xs(sym1, level='name')
sym2df = newticker.xs(sym2, level='name')
symdiff = sym1df.values - sym2df.values
dfdiff.loc[(slice(None), sym1, sym2), :] = symdiff
#
return dfdiff
我敢肯定,有一种更优雅的方式来做我想要的事情。我会寻求任何帮助。
答案 0 :(得分:1)
您有一个结构良好的数据框,我们需要做的只是merge
,然后是groupby
df=newticker.reset_index()# using the index for merge key
newdf=df.merge(df,on='index')
newdf=newdf.loc[lambda x:['name_x']!=x['name_y']]
newdf=newdf.set_index(['index','name_x','name_y'])
-newdf.groupby(newdf.columns.str.split('_').str[0],
axis=1).diff().dropna(1)
Out[90]:
a_y c_y z_y
index name_x name_y
0 foo bar 11.0 7.0 -0.0
baz 8.0 6.0 -0.0
toto 3.0 5.0 -0.0
titi 10.0 8.0 -0.0
bar foo -11.0 -7.0 -0.0
baz -3.0 -1.0 -0.0
toto -8.0 -2.0 -0.0
titi -1.0 1.0 -0.0
baz foo -8.0 -6.0 -0.0
bar 3.0 1.0 -0.0
toto -5.0 -1.0 -0.0
titi 2.0 2.0 -0.0
toto foo -3.0 -5.0 -0.0
bar 8.0 2.0 -0.0
baz 5.0 1.0 -0.0
titi 7.0 3.0 -0.0
titi foo -10.0 -8.0 -0.0
bar 1.0 -1.0 -0.0
baz -2.0 -2.0 -0.0
toto -7.0 -3.0 -0.0
1 foo bar 4.0 5.0 -0.0
baz 2.0 3.0 -0.0
toto 3.0 5.0 -0.0
titi 2.0 6.0 -0.0
bar foo -4.0 -5.0 -0.0
baz -2.0 -2.0 -0.0
toto -1.0 -0.0 -0.0
titi -2.0 1.0 -0.0
baz foo -2.0 -3.0 -0.0
bar 2.0 2.0 -0.0
toto 1.0 2.0 -0.0
titi -0.0 3.0 -0.0
toto foo -3.0 -5.0 -0.0
bar 1.0 -0.0 -0.0
baz -1.0 -2.0 -0.0
titi -1.0 1.0 -0.0
titi foo -2.0 -6.0 -0.0
bar 2.0 -1.0 -0.0
baz -0.0 -3.0 -0.0
toto 1.0 -1.0 -0.0