Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用于查找最大值行的groupby正在将对象转换为datetime_Python_Pandas - Fatal编程技术网

Python 用于查找最大值行的groupby正在将对象转换为datetime

Python 用于查找最大值行的groupby正在将对象转换为datetime,python,pandas,Python,Pandas,我想按两个变量['CIN','calendar']分组,并返回该组的行,其中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 0

我想按两个变量['CIN','calendar']分组,并返回该组的行,其中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'时,该列被转换为datetime!请参见下面的示例,观察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

因为它可以工作,我想我选择它是为了简单。

熊猫试图通过识别类似日期的列并将该列转换为datetime64数据类型来提供额外的帮助。这里太过咄咄逼人了

一种解决方法是使用
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

技术细节:当使用groupbyapply时,当单个数据帧(由应用的函数返回)粘回到一个数据帧中时,Pandas尝试猜测列是否 具有对象数据类型的是类似日期的对象,如果是这样的话。如果值是字符串,它将尝试将其解析为 使用
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列转换为日期。因为没有错误发生,它认为它只是帮了你一把:)

你是个天才!这件事我已经搞了好几天了。谢谢。当我在实际数据上运行这个时,我得到了“IndexingError:Unalignable boolean Series key Providered”,我不确定如何调查这个问题?你见过吗?为什么我需要“aType(bool)”?尝试在
onemax
函数中将
return mask
更改为
return mask.values
。这将返回一个NumPy数组,而不是一个序列。由于NumPy数组没有索引,因此不应该存在“不可对齐的布尔级数”问题。这可能会解决问题。需要使用
astype(bool)
,因为
transform
方法将
onemax
返回的布尔值转换为整数。要将这些值用作布尔掩码,我们需要将它们重新转换为布尔。这在我看来很难看,但我还没有调查熊猫为什么选择这样做。同意,再次感谢。非常有帮助和信息量大。