基本上,我想计算按2个变量分组的最频繁项的数量。我使用以下代码:
dfgrouped = data[COLUMNS.copy()].groupby(['Var1','Var2']).agg(lambda x: stats.mode(x)[1])
此代码有效,但不适用于具有Nan值的列,因为NaN值是浮点型而其他是str。因此显示此错误:
'<' not supported between instances of 'float' and 'str'
我想忽略其余的NaN值和计数模式。所以str(x)不是解决方案。 scipy.stats.mode(x,nan_policy ='omit')也不起作用,并且出现错误:
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
请您给我一个建议,以解决该问题。 谢谢
答案 0 :(得分:1)
我认为需要dropna
才能删除NaN
:
dfgrouped = data[COLUMNS.copy()].groupby(['Var1','Var2']).agg(lambda x: stats.mode(x.dropna())[1])
如果需要为所有NaN组设置NaN
:
dfgrouped = (data[COLUMNS.copy()]
.groupby(['Var1','Var2'])
.agg(lambda x: None if x.isnull().all() else stats.mode(x.dropna())[1]))
答案 1 :(得分:1)
您可以先执行dropna
,然后再执行groupby
。如果尝试在聚合中进行dropna
,则具有所有NaN
值的组可能会产生stats.mode
的错误。
这是一个最小的例子:
import pandas as pd
import numpy as np
from scipy import stats
df = pd.DataFrame([[1, 2, np.nan], [1, 2, 'hello'], [1, 2, np.nan],
[5, 6, 'next'], [5, 6, np.nan], [5, 6, 'next'],
[7, 8, np.nan], [7, 8, np.nan], [7, 8, np.nan]],
columns=['Var1', 'Var2', 'Value'])
res = df.dropna(subset=['Value'])\
.groupby(['Var1', 'Var2'])\
.agg(lambda x: stats.mode(x)[1][0])
print(res)
Value
Var1 Var2
1 2 1
5 6 2
如果您需要保留包含所有NaN
值的组,则可以捕获IndexError
:
def mode_calc(x):
try:
return stats.mode(x.dropna())[1][0]
except IndexError:
return np.nan
res = df.groupby(['Var1', 'Var2'])\
.agg(mode_calc)
print(res)
Value
Var1 Var2
1 2 1.0
5 6 2.0
7 8 NaN
答案 2 :(得分:0)
nan的类型为float并且np.nan == np.nan也是False。如果需要将它们分组在一起,可以尝试如下操作:
# First replace nan values with something like 'Unavailable'
data.fillna('Unavailable', inplace=True)
# Then re-run your code
dfgrouped = data[COLUMNS.copy()].groupby(['Var1','Var2']).agg(lambda x: stats.mode(x)[1])
这会将所有不可用项分组在一起。希望有帮助