用约束词典查询熊猫

时间:2015-11-21 05:17:52

标签: python pandas data-cleansing

我想在大熊猫的某些年内退出几个月。我有这样的约束{month:year}。

 [{1: 2003},
 {2: 2008},
 {3: 2011},
 {4: 2012},
 {5: 2008},
 {6: 2008},
 {7: 2002},
 {8: 2006},
 {9: 2005},
 {10: 2013},
 {11: 2005},
 {12: 2001}]

意味着我想要数据框中的2003年1月,2008年2月等。我将“月”和“年”作为数据框中的两列。

我想要执行这个错误代码的东西(但想法很清楚):

df[(df['Month'] == key for key in dict) & (df['Year'] == dict[key])]

3 个答案:

答案 0 :(得分:3)

您可以使用 lambda 在Pandas中执行高级过滤。

<强>假设:

  1. 所有月份和年份都是整数
  2. 约束在list of dict类型
  3. 如果数据类型不同,您可以修改以下行以解决您的问题。

    生成随机数据以填充数据框

    In [1]: from random import randint 
    
    In [2]: months = [randint(1, 12) for x in range(10)]
    
    In [3]: years = [randint(2000, 2020) for x in range(10)]
    
    In [4]: months
    Out[4]: [12, 3, 7, 6, 10, 10, 11, 9, 9, 10]
    
    In [5]: years
    Out[5]: [2017, 2016, 2001, 2004, 2015, 2013, 2001, 2020, 2013, 2016]
    
    In [6]: import pandas as pd
    
    In [7]: df = pd.DataFrame()
    
    In [8]: df['Month'] = months
    
    In [9]: df['Year'] = years
    

    <强> 2。使用给定的list of dict并将其转换为list of tuple以便于编码

    注意:一旦你理解我想要完成的任务,你可以根据自己的意愿改变你的约束。

    In [10]: filterDict = [{1: 2003}, {2: 2008}, {3: 2011}, {4: 2012}, {5: 2008}, {6: 2008}, {7: 2002}, {8: 2006}, {9: 2005}, {3: 2016}, {6: 2004}, {12: 2001}]
    
    In [11]: filterList = [d.items()[0] for d in filterDict]
    

    第3。使用lambda过滤数据框

    In [12]: df[df.apply(lambda x: (x['Month'],x['Year']) in filterList, axis=1)]
    Out[12]: 
       Month  Year
    1      3  2016
    3      6  2004
    

    过滤前的原始数据供您参考:

    In [13]: df
    Out[13]: 
       Month  Year
    0     12  2017
    1      3  2016
    2      7  2001
    3      6  2004
    4     10  2015
    5     10  2013
    6     11  2001
    7      9  2020
    8      9  2013
    9     10  2016
    

答案 1 :(得分:1)

执行此操作的一个方法是将年份和月份作为浮点数加起来并使用:

In [11]: months = set(year + month * 0.01 for i in d for (month, year) in i.items())

In [12]: months
Out[12]: {2001.12, 2002.07, 2003.01, 2005.09, 2006.08, 2005.11, 2008.02, 2008.05, 2008.06, 2011.03, 2012.04, 2013.1}

然后检查同一年。月是否在DataFrame中:

In [21]: df = pd.DataFrame([[2001, 12], [2001, 3], [2002, 7]], columns=["Year", "Month"])

In [22]: df
Out[22]:
   Year  Month
0  2001     12
1  2001      3
2  2002      7

In [23]: (df["Year"] + 0.01 * df["Month"]).isin(months)
Out[23]:
0     True
1    False
2     True
dtype: bool

所以你想要的子帧是:

In [24]: df[(df["Year"] + 0.01 * df["Month"]).isin(months)]
Out[24]:
   Year  Month
0  2001     12
2  2002      7

* 它有效,但感觉有点脏......

答案 2 :(得分:0)

from functools import reduce
df = pandas.DataFrame(dict(col1=[1,2], col2=['a','b']))
   col1 col2
0     1    a
1     2    b
params = dict(col1=2, col2='b')
mask = reduce(lambda x,y: x & y, [df[k] == v for k,v in params.items()])
print(df[mask])

   col1 col2
1     2    b