groupby 查找具有最大值的行正在将对象转换为日期时间
groupby to find row with max value is converting object to datetime
我想按两个变量 ['CIN'、'calendar'] 和 return 分组,其中 MCelig 列在该特定组中最大。很可能多行会有最大值,但我只想要一行。
例如:
AidCode CIN MCelig calendar
0 None 1e 1 2014-03-08
1 01 1e 2 2014-03-08
2 01 1e 3 2014-05-08
3 None 2e 4 2014-06-08
4 01 2e 5 2014-06-08
因为前两行是一组,所以我想要MCelig =2的行。
我想到了这条线
test=dfx.groupby(['CIN','calendar'], group_keys=False).apply(lambda x: x.ix[x.MCelig.idxmax()])
并且它似乎有效,除非我将所有值的所有 'None' 或 'np.nan' 用于列的组中的所有值,该列将转换为日期时间!请参阅下面的示例并观察 AidCode 从一个对象到一个日期。
import datetime as DT
import numpy as np
d = {'CIN' : pd.Series(['1e','1e','1e','2e','2e']),
'AidCode' : pd.Series([np.nan,'01','01',np.nan,'01']),
'calendar' : pd.Series([DT.datetime(2014, 3, 8), DT.datetime(2014, 3, 8),DT.datetime(2014, 5, 8),DT.datetime(2014, 6, 8),DT.datetime(2014, 6, 8)]),
'MCelig' : pd.Series([1,2,3,4,5])}
dfx=pd.DataFrame(d)
#testing whether it was just the np.nan that was the problem, it isn't
#dfx = dfx.where((pd.notnull(dfx)), None)
test=dfx.groupby(['CIN','calendar'], group_keys=False).apply(lambda x: x.ix[x.MCelig.idxmax()])
产出
Out[820]:
AidCode CIN MCelig calendar
CIN calendar
1e 2014-03-08 2015-01-01 1e 2 2014-03-08
2014-05-08 2015-01-01 1e 3 2014-05-08
2e 2014-06-08 2015-01-01 2e 5 2014-06-08
更新:
刚刚找到这个简单的解决方案
x=dfx.sort(['CIN','calendar',"MCelig"]).groupby(["CIN",'calendar'], as_index=False).last();x
因为它有效,我想我选择它是为了简单起见。
Pandas 试图通过识别看起来像日期的列并将该列转换为 datetime64 dtype 来提供额外的帮助。它在这里过于激进了。
解决方法是使用 transform
为每个选择最大行数的组生成 布尔掩码 :
def onemax(x):
mask = np.zeros(len(x), dtype='bool')
idx = np.argmax(x.values)
mask[idx] = 1
return mask
dfx.loc[dfx.groupby(['CIN','calendar'])['MCelig'].transform(onemax).astype(bool)]
产量
AidCode CIN MCelig calendar
1 01 1e 2 2014-03-08
2 01 1e 3 2014-05-08
4 01 2e 5 2014-06-08
技术细节:当使用 groupby-apply 时,当单独的 DataFrame(由应用函数返回)被粘合回一个 DataFrame 时,Pandas 试图猜测列是否
with object dtype 是类似日期的对象,如果是这样,将列转换为
实际日期 dtype。如果值是字符串,它会尝试将它们解析为
日期使用 dateutil.parser
:
无论好坏,dateutil.parser
将 '01'
解释为日期:
In [37]: import dateutil.parser as DP
In [38]: DP.parse('01')
Out[38]: datetime.datetime(2015, 1, 1, 0, 0)
这会导致 Pandas 尝试将整个 AidCode 列转换为日期。由于没有发生错误,它认为它只是帮助了你:)
我想按两个变量 ['CIN'、'calendar'] 和 return 分组,其中 MCelig 列在该特定组中最大。很可能多行会有最大值,但我只想要一行。
例如:
AidCode CIN MCelig calendar
0 None 1e 1 2014-03-08
1 01 1e 2 2014-03-08
2 01 1e 3 2014-05-08
3 None 2e 4 2014-06-08
4 01 2e 5 2014-06-08
因为前两行是一组,所以我想要MCelig =2的行。
我想到了这条线
test=dfx.groupby(['CIN','calendar'], group_keys=False).apply(lambda x: x.ix[x.MCelig.idxmax()])
并且它似乎有效,除非我将所有值的所有 'None' 或 'np.nan' 用于列的组中的所有值,该列将转换为日期时间!请参阅下面的示例并观察 AidCode 从一个对象到一个日期。
import datetime as DT
import numpy as np
d = {'CIN' : pd.Series(['1e','1e','1e','2e','2e']),
'AidCode' : pd.Series([np.nan,'01','01',np.nan,'01']),
'calendar' : pd.Series([DT.datetime(2014, 3, 8), DT.datetime(2014, 3, 8),DT.datetime(2014, 5, 8),DT.datetime(2014, 6, 8),DT.datetime(2014, 6, 8)]),
'MCelig' : pd.Series([1,2,3,4,5])}
dfx=pd.DataFrame(d)
#testing whether it was just the np.nan that was the problem, it isn't
#dfx = dfx.where((pd.notnull(dfx)), None)
test=dfx.groupby(['CIN','calendar'], group_keys=False).apply(lambda x: x.ix[x.MCelig.idxmax()])
产出
Out[820]:
AidCode CIN MCelig calendar
CIN calendar
1e 2014-03-08 2015-01-01 1e 2 2014-03-08
2014-05-08 2015-01-01 1e 3 2014-05-08
2e 2014-06-08 2015-01-01 2e 5 2014-06-08
更新:
刚刚找到这个简单的解决方案
x=dfx.sort(['CIN','calendar',"MCelig"]).groupby(["CIN",'calendar'], as_index=False).last();x
因为它有效,我想我选择它是为了简单起见。
Pandas 试图通过识别看起来像日期的列并将该列转换为 datetime64 dtype 来提供额外的帮助。它在这里过于激进了。
解决方法是使用 transform
为每个选择最大行数的组生成 布尔掩码 :
def onemax(x):
mask = np.zeros(len(x), dtype='bool')
idx = np.argmax(x.values)
mask[idx] = 1
return mask
dfx.loc[dfx.groupby(['CIN','calendar'])['MCelig'].transform(onemax).astype(bool)]
产量
AidCode CIN MCelig calendar
1 01 1e 2 2014-03-08
2 01 1e 3 2014-05-08
4 01 2e 5 2014-06-08
技术细节:当使用 groupby-apply 时,当单独的 DataFrame(由应用函数返回)被粘合回一个 DataFrame 时,Pandas 试图猜测列是否
with object dtype 是类似日期的对象,如果是这样,将列转换为
实际日期 dtype。如果值是字符串,它会尝试将它们解析为
日期使用 dateutil.parser
:
无论好坏,dateutil.parser
将 '01'
解释为日期:
In [37]: import dateutil.parser as DP
In [38]: DP.parse('01')
Out[38]: datetime.datetime(2015, 1, 1, 0, 0)
这会导致 Pandas 尝试将整个 AidCode 列转换为日期。由于没有发生错误,它认为它只是帮助了你:)