python-3.x pandas multiindex -使用列时如何选择第二级?

wrrgggsh  于 2022-12-24  发布在  Python
关注(0)|答案(7)|浏览(189)

我有一个带有此索引的 Dataframe :

index = pd.MultiIndex.from_product([['stock1','stock2'...],['price','volume'...]])

对于df['stock1']来说,这是一个有用的结构,但是我如何选择所有的价格数据呢?我对文档没有任何意义。
我尝试了以下方法,但没有成功:x一个月一个月x一个月二个月一个月x一个月三个月一个月x一个月四个月
如果这种指数风格被普遍认为是一个坏主意,那么什么是更好的选择呢?我应该选择一个多指数的股票指数,作为时间序列上的标签,而不是列水平?
多谢了
EDIT-我对列使用了多索引,而不是索引(我的措辞占了上风)。文档中的示例侧重于多级索引而不是列结构。

kkih6yb8

kkih6yb81#

同样使用John的数据样本:
使用xs()是对MultiIndex进行切片的另一种方法:

df
               0
stock1 price   1
       volume  2
stock2 price   3
       volume  4
stock3 price   5
       volume  6

df.xs('price', level=1, drop_level=False)
              0
stock1 price  1
stock2 price  3
stock3 price  5

或者,如果用MultiIndex代替列:

df
  stock1        stock2        stock3       
   price volume  price volume  price volume
0      1      2      3      4      5      6

df.xs('price', axis=1, level=1, drop_level=False)
  stock1 stock2 stock3
   price  price  price
0      1      3      5
rpppsulh

rpppsulh2#

使用@JohnZwinck的数据样本:

In [132]: df
Out[132]:
               0
stock1 price   1
       volume  2
stock2 price   3
       volume  4
stock3 price   5
       volume  6
    • 备选案文1:**
In [133]: df.loc[(slice(None), slice('price')), :]
Out[133]:
              0
stock1 price  1
stock2 price  3
stock3 price  5
    • 备选案文2:**
In [134]: df.loc[pd.IndexSlice[:, 'price'], :]
Out[134]:
              0
stock1 price  1
stock2 price  3
stock3 price  5
    • 更新日期:**

但是如果对于第二个索引,我想选择除price之外的所有值,并且有多个值,所以枚举不是一个选项。是否有类似slice(~' price ')的东西
首先,我们来命名指数级别:

df = df.rename_axis(["lvl0", "lvl1"])

现在我们可以使用df.query()方法:

In [18]: df.query("lvl1 != 'price'")
Out[18]:
               0
lvl0   lvl1
stock1 volume  2
stock2 volume  4
stock3 volume  6
vi4fp9gy

vi4fp9gy3#

我发现访问具有MultiIndex列的DataFrame中的第二级列的最直观的解决方案是将.locslice()一起使用。
如果您的DataFrame带有

df
  stock1        stock2        stock3       
   price volume  price volume  price volume
0      1      2      3      4      5      6
1      2      3      4      5      6      7

使用df.loc[:, (slice(None), "price")]
将传送具有"price"的子列的所有列

stock1  stock2  stock3       
   price   price   price 
0      1       3       5
1      2       4       6

df.loc[:, (slice(None), "price")]中,loc :的第一个参数传递所有行的结果,第二个参数(slice(None), "price")是一个元组,负责选择所有第一级列(slice(None))和所有名称为"price"的第二级列。

xfb7svmp

xfb7svmp4#

df.unstack()将“撕掉”MultiIndex的最后一层,使DataFrame更加常规,每种数据类型一列。例如:

index = pd.MultiIndex.from_product([['stock1','stock2','stock3'],['price','volume']])
df = pd.DataFrame([1,2,3,4,5,6], index)
print(df.unstack())

为您提供:

0       
       price volume
stock1     1      2
stock2     3      4
stock3     5      6
xfb7svmp

xfb7svmp5#

虽然@MaxU 's是更好的答案,但我想在这里指出,我们也可以单独地reset_index MultiIndex的任何部分,例如,假设:

df = pd.DataFrame({
    'price':range(6),
    'stocks': [f'stock{i//2}' for i in range(6)],
    'attr':['price','volume']*3
}).set_index(['stocks','attr'])

导致DF:

price
stocks attr         
stock0 price       0
       volume      1
stock1 price       2
       volume      3
stock2 price       4
       volume      5

例如:

df_rst = df.reset_index('attr')
df_rst[df_rst['attr']=='price']

将导致:

0aydgbwb

0aydgbwb6#

您也可以先交换级别,然后按第一个级别进行选择(基于@ntg的sample data):

df = pd.DataFrame({
    'value': range(6),
    'stocks': [f'stock{i // 2}' for i in range(6)],
    'attr': ['price', 'volume'] * 3
}).set_index(['stocks', 'attr'])

df.swaplevel().loc["price"]

        value
stocks       
stock0      0
stock1      2
stock2      4

也适用于axis=1的列。

iqxoj9l9

iqxoj9l97#

我还注意到你错过了这个选项:

df.loc[:,"price"]

作为时间数据的最佳实践,将其保存在与行对应的列中,最好是Python中的datetime对象(Pandas内置了对它的特性支持),可以使用掩码语法只获取与您感兴趣的时间。
这就是你访问数据框中一列的方式。但是对于多列,我们可以传递一个列表,或者一个冒号来获取全部:

df.loc[:,["price","volume"]] 
#or
df.loc[:,:]

一种有用的查询方式(而且快速)是使用掩码指定哪些行/列满足所需的条件:

Mask=df.loc[:,"price"]>50.0
df.loc[Mask, "stock"] #should return the stock prices greater than 50bucks.

希望这能有所帮助,并一如既往地随时跟进这个答案,如果我完全误解了你的问题,我很乐意进一步帮助。

相关问题