使用约束字典查询 Pandas
Querying Pandas with a Dictionary of Constraints
我正试图用 pandas 在某些年份中抽出几个月。我有这样返回的约束 {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 月等。我有 "Month" 和 "Year" 作为数据框中的两列。
我想要一些东西来执行这个不正确的代码(但思路很明确):
df[(df['Month'] == key for key in dict) & (df['Year'] == dict[key])]
一个 hack* 方法是将年份和月份作为浮点数相加并使用:
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 中是否有相同的 year.month:
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
*可以用但是感觉有点脏...
您可以使用 lambda 在 Pandas 中执行高级过滤。
假设:
- 所有月份和年份都是整数
- 约束在
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
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
我正试图用 pandas 在某些年份中抽出几个月。我有这样返回的约束 {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 月等。我有 "Month" 和 "Year" 作为数据框中的两列。
我想要一些东西来执行这个不正确的代码(但思路很明确):
df[(df['Month'] == key for key in dict) & (df['Year'] == dict[key])]
一个 hack* 方法是将年份和月份作为浮点数相加并使用:
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 中是否有相同的 year.month:
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
*可以用但是感觉有点脏...
您可以使用 lambda 在 Pandas 中执行高级过滤。
假设:
- 所有月份和年份都是整数
- 约束在
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
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