python - 使用 MultiIndex 过滤

标签 python pandas filtering multi-index

我有一个像这样的 Pandas DataFrame:

import numpy as np
import pandas as pd

np.random.seed(1234)
midx = pd.MultiIndex.from_product([['a', 'b', 'c'], pd.date_range('20130101', periods=6)], names=['letter', 'date'])
df = pd.DataFrame(np.random.randn(len(midx), 1), index=midx)

那个数据框看起来像这样:

                        0
letter      date    
  a     2013-01-01  0.471435
        2013-01-02  -1.190976
        2013-01-03  1.432707
        2013-01-04  -0.312652
        2013-01-05  -0.720589
        2013-01-06  0.887163
  b     2013-01-01  0.859588
        2013-01-02  -0.636524
        2013-01-03  0.015696
        2013-01-04  -2.242685
        2013-01-05  1.150036
        2013-01-06  0.991946
  c     2013-01-01  0.953324
        2013-01-02  -2.021255
        2013-01-03  -0.334077
        2013-01-04  0.002118
        2013-01-05  0.405453
        2013-01-06  0.289092

我想做的是根据 date 的条件保留所有行,这取决于 letter。例如,

  • 对于字母a,我想保留所有行,这样日期在“20130102”和“20130105”(包括在内)之间
  • 对于字母 b,我想保留所有行,这样 date == "20130103"
  • 对于字母c,我想保留所有行,这样日期在“20130103”和“20130105”(包括在内)之间

例如,所有这些信息都可以存储在字典中。

dictionary = {"a": slice("20130102", "20130105"),
              "b": "20130103",
              "c": slice("20130103", "20130105")}

有没有一种简单的方法可以用 pandas 计算这个?我没有找到有关此类过滤的任何信息。

最佳答案

您可以使用query,它就是为这种选择标准而设计的。

如果您稍微修改您的字典,您可以在列表理解的帮助下生成您想要的查询:

In : dictionary
Out:
{'a': ('20130102', '20130105'),
 'b': ('20130103', '20130103'),
 'c': ('20130103', '20130105')}

In : df.query(
          ' or '.join("('{}' <= date <= '{}' and letter == '{}')".format(*(v + (k,))) 
          for k, v in dictionary.items())
         )
Out:
                          0
letter date
a      2013-01-02 -1.190976
       2013-01-03  1.432707
       2013-01-04 -0.312652
       2013-01-05 -0.720589
b      2013-01-03  0.015696
c      2013-01-03 -0.334077
       2013-01-04  0.002118
       2013-01-05  0.405453

有关查询语句实际执行的操作的更多信息,请参阅列表理解的详细信息:

In : (' or '.join("('{}' <= date <= '{}' and letter == '{}')".format(*(v + (k,)))
          for k, v in dictionary.items()))
Out: "('20130102' <= date <= '20130105' and letter == 'a') or 
          ('20130103' <= date <= '20130105' and letter == 'c') or
          ('20130103' <= date <= '20130103' and letter == 'b')"

关于python - 使用 MultiIndex 过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49237656/

相关文章:

python - 两个 pd.Timestamp 对象之间每天上午 9 点的 pd.date_range

php - (如何)过滤器/参数可以与 Apigility 中的数据库连接服务一起使用吗?

python - 使用破折号 VS 下划线的 Django 模板命名

python - 如何计算 pandas 中两个数据帧的平均值?

python - x.iloc[1] ['x'] 和 x ['x'].iloc[1] 有什么区别

sorting - 在排序和过滤后,如何重新选中剑道网格中的复选框?

电子邮件数组上的 PHP OOP 过滤器验证

java - 为什么Java虚拟机中没有GIL?为什么 Python 这么需要一个?

python - Pandas 中具有特定总长度的动态索引

python - Pandas "join"奇怪