将公式应用于多索引列 Python

Posted

技术标签:

【中文标题】将公式应用于多索引列 Python【英文标题】:Apply formula to Multi-index column Python 【发布时间】:2015-06-06 20:35:06 【问题描述】:

提前感谢您的帮助。

对 pandas 来说足够新,会很危险。

想要将公式和标签结果应用于多索引数据框。

以下作品:

import pandas as pd
import numpy as np 

N = 100
dates = pd.date_range('19971002', periods=N, freq='B')
df =pd.DataFrame(np.random.randn(len(dates),2),index=dates,columns=list('AB')) 
df1 =pd.DataFrame(np.random.randn(len(dates),2),index=dates,columns=list('AB'))

我添加了两列,“模式”(用于标签)和“增量”(公式)。

df['pattern'] = 'foo'
df['delta'] = df.A - df.B
df.loc[(df.A > df.B),'pattern']= 'bar'
df.loc[(df.A < df.B),'pattern'] = 'bat'  

df.head()

                A       B          pattern  delta
1997-10-02  -0.685254   2.264847    bat -2.950101
1997-10-03  -1.087783   1.953508    bat -3.041291
1997-10-06  1.094727    0.612298    bar 0.482429
1997-10-07  -1.093363   1.791276    bat -2.884639
1997-10-08  -0.916725   2.225537    bat -3.142262

我在连接两个数据帧时遇到了麻烦。想要将 df 和 df1 组合到单个数据框中,以便我可以获得“bar”和“bat”的最高值,以及标识数据(行)是来自 DF 还是 DF1 的附加列。

data = pd.DataFrame(pd.concat([df, df1], axis=1, keys=['DF', 'DF1']))

df.head()
            DF                      DF1
            A           B           A           B
1997-10-02  0.360254    -0.477511   -0.017894   0.226474
1997-10-03  -0.226963   -1.302804   -1.615174   -0.330607
1997-10-06  0.524860    2.597518    -0.041241   1.432354
1997-10-07  -0.672445   1.741740    0.011852    0.013495
1997-10-08  0.969295    0.240990    0.682385    0.875781

我尝试了几种方法,例如:

data['value'] = 'foo'
data['delta'] = data.A - data.B
data.loc[(data.A > data.B),'pattern']= 'bar'
data.loc[(data.A < data.B),'pattern'] = 'bat'  

并获得错误消息。

Gut 告诉我我需要先分组然后应用公式,我可以处理(我认为),但我该如何带上 label('pattern') 呢?

目标是:

            Column pattern delta
1997-10-02  DF     bat     -2.950101
1997-10-03  DF     bat     -3.041291
1997-10-06  DF1    bar     0.482429
1997-10-07  DF     bat     -2.884639
1997-10-08  DF1    bat     -3.142262

再次感谢您!

【问题讨论】:

【参考方案1】:

IIUC,您可以通过堆叠然后执行 groupby 来实现大部分目标:

data = data.stack(level=0)
data['pattern'] = 'foo'
data['delta'] = data.A - data.B
data.loc[(data.A > data.B),'pattern']= 'bar'
data.loc[(data.A < data.B),'pattern'] = 'bat'  
final = data.loc[data.groupby(level=0)["delta"].idxmax()]

给了我类似的东西

>>> final
                       A         B pattern     delta
1997-10-02 DF   0.536219 -1.019708     bar  1.555927
1997-10-03 DF   1.702837 -1.204639     bar  2.907477
1997-10-06 DF1  0.448117  0.302420     bar  0.145697
1997-10-07 DF  -0.563475  0.778225     bat -1.341700
1997-10-08 DF   1.072564  0.695792     bar  0.376772
1997-10-09 DF   0.739936 -0.290353     bar  1.030290
1997-10-10 DF1 -0.124411  0.351603     bat -0.476014
1997-10-13 DF1 -0.390445 -0.208104     bat -0.182341
1997-10-14 DF1 -0.153270 -1.464505     bar  1.311235
1997-10-15 DF1  0.081881 -1.382577     bar  1.464458

您可以在其中重置索引并根据需要更改列名。这是有效的,因为堆叠将列中的 DF 拉出:

>>> data.stack(level=0)
                       A         B
1997-10-02 DF   0.060752 -0.858375
           DF1  0.923508 -1.188595
1997-10-03 DF  -0.820430 -1.964643
           DF1 -0.989516 -0.916772
[...]

最后,因为.idxmax() 为我们提供了delta 达到最大值的索引,我们可以使用它来索引框架。


除此之外:这更符合个人喜好,但我喜欢使用np.sign(1 表示正数,0 表示 0,-1 表示负数)然后 replace 而不是三行用于您的 @987654328 @ 翻译。例如:

np.sign(data["delta"]).replace(1: "bar", 0: "foo", -1: "bat")

【讨论】:

以上是关于将公式应用于多索引列 Python的主要内容,如果未能解决你的问题,请参考以下文章

Python/Pandas - 查询多索引列 [重复]

如何将多索引列转换为熊猫数据框的单索引列?

在多索引列上合并pandas数据帧

将 Pandas 数据帧与多索引列和不规则时间戳连接起来

枢轴熊猫数据框具有多索引列

如何将熊猫数据框多索引列移动到 2 行