假设我有这个 df:
import pandas as pd
import numpy as np
# Sample MultiIndex DataFrame
index = pd.date_range('2023-01-01', '2023-01-05', freq='D')
codes = ['A', 'B', 'C']
columns = pd.MultiIndex.from_product([['MA1', 'MA2', 'MA3', 'MA4', 'MA5'], codes], names=['MA', 'code'])
data = np.random.randint(1, 10, size=(len(index), len(columns)))
df = pd.DataFrame(data, index=index, columns=columns)
df
索引是日期时间,在多索引列上,级别 0 由 5 个不同的移动平均线 (MA1 - MA5) 组成,级别 1 由 3 个代码(A、B 和 C)组成。 (真正的df要大得多)
我尝试将 MA1 的 A、B 和 C 值与 MA2、MA3、MA4 和 MA5 中的每一个进行比较,并创建一个 new_df。
new_df 将具有相同的日期时间索引,以及相同的多索引列(A、B 和 C)的级别 1,但级别 0 将不同:'MA1>MA2'、'MA1>MA3'、'MA1>MA4 ', 'MA1>MA5'.
new_df 将由 1、-1 和 0 组成。如果值 >,则为 1;如果 <, and 0 if same.
,则为 -1因此,对于每个日期,new_df 的第一个 0 级列('MA1>MA2')会将 A B 和 C 的 MA1 值与其 MA2 值进行比较,得出 1、-1 或 0。
new_df 的第二级 0 列('MA1>MA3')将比较 A、B 和 c 的 MA1 值与 MA3 值等
我遇到了无效索引错误,试图获取正确的切片进行比较......任何人都可以帮忙吗?
谢谢!
您可以从
MA1
中减去数据框中的所有内容,根据需要重命名列,然后将减法结果与 0 进行比较以生成所需的结果:
def compare_zero(x):
return 1 if x > 0 else -1 if x < 0 else 0
out = (df.loc[:,'MA1'] - df).drop(columns='MA1')
out.columns = pd.MultiIndex.from_tuples([(f'MA1>{a}',b) for a,b in out.columns], names=out.columns.names)
out = out.applymap(compare_zero)
对于我的样本数据
MA MA1 MA2 MA3 MA4 MA5
code A B C A B C A B C A B C A B C
2023-01-01 5 6 5 4 6 8 7 3 8 9 8 2 3 1 6
2023-01-02 9 7 3 5 3 7 4 9 5 6 8 7 9 3 4
2023-01-03 2 9 4 9 2 5 6 3 4 3 7 3 4 1 8
2023-01-04 7 1 7 9 1 1 6 1 7 1 8 3 2 8 7
2023-01-05 1 6 2 1 8 2 4 9 4 9 9 7 3 1 4
这给出:
MA MA1>MA2 MA1>MA3 MA1>MA4 MA1>MA5
code A B C A B C A B C A B C
2023-01-01 1 0 -1 -1 1 -1 -1 -1 1 1 1 -1
2023-01-02 1 1 -1 1 -1 -1 1 -1 -1 0 1 -1
2023-01-03 -1 1 -1 -1 1 0 -1 1 1 -1 1 -1
2023-01-04 -1 0 1 1 0 0 1 -1 1 1 -1 0
2023-01-05 0 -1 0 -1 -1 -1 -1 -1 -1 -1 1 -1