2015-11-21 5 views
3

Я пытаюсь вытащить месяцы в течение определенных лет с помощью панд. У меня есть ограничения, возвращаемые как таковые {month: year}.Querying Pandas with Dictionary of Constraints

[{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 г., февраль 2008 г. и т. Д. Из фрейма данных. У меня есть «Месяц» и «Год» как два столбца в фрейме данных.

Я хочу что-то, что выполняет этот неправильный код (но идея ясна):

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

это то, как ваш словарь выглядит? вы действительно вставили список словарей выше. –

ответ

3

Вы можете использовать лямбда выполнить расширенную фильтрацию в панд.

Предположение:

  1. всего месяц и год является целыми
  2. ограничения в list of dict типа

Вы можете изменить следующие строки номеров ваших проблем, если типы данных различны.

Генерация случайных данных для заполнения данных кадра

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 для фильтрации dataframe

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

Один хак * сделать это, чтобы добавить до года и месяца, как поплавок, и использовать это:

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} 

затем проверить этот же year.month находится в 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 

* Это работает, но чувствует немного грязный ...