gpt4 book ai didi

python - 在 pandas 系列上使用 apply 方法获取 TypeError 'Series' 对象是可变的,因此无法对其进行哈希处理

转载 作者:行者123 更新时间:2023-12-01 03:20:58 25 4
gpt4 key购买 nike

我有两个数据框D1D2。我想要实现的是对于 D1D2 中非 int 和非 float 类型的任何列对,我想使用公式

 |A intersect B|/ |A union B|

我首先定义了一个函数

def jaccard_d(series1, series2):
if (series1.dtype is not (pd.np.dtype(int) or pd.np.dtype(float))) and (series2.dtype is not (pd.np.dtype(int) or pd.np.dtype(float))):
series1 = series1.drop_duplicates()
series2 = series2.drop_duplicates()
return len(set(series1).intersection(set(series2))) /len(set(series1).union(set(series2)))
else:
return np.nan

然后我所做的是首先循环 D1 中的所有列,然后对于 D1 中的每个固定列,我使用 apply我的 jaccard_d 函数。我尽量避免编写 2 层循环。也许有更好的方法而不需要编写任何循环?

DC = dict.fromkeys(list(D1.columns))
INN = list(D2.columns)
for col in D1:
DC[col] = dict(zip(INN, D2.apply(jaccard_d,D1[col])))

首先,我不确定我是否正确使用了 apply 函数,即我的 jaccard_d 函数接受 2 个系列作为输入,但是对于每次迭代,我都有D1[col] 作为一个系列,我想使用 applyD1[col] 应用于 D2< 的所有列

其次,我收到此错误“'Series'对象是可变的,因此它们不能被散列”,我不太明白。如有任何意见,我们将不胜感激。

我尝试编写一个 2 层循环并使用我的函数 jaccard_d 来执行此操作。有用。但我想编写更高效的代码。

最佳答案

因此,经过一番摸索,准确找到错误发生的位置,并检查 apply 文档,我推断您需要这样调用 apply :

 D2.apply(jaccard_d, args=(D1[col],))

相反,您使用的是

 D2.apply(jaccard_d, axis=D1[col])

==================

我可以用一个简单的数据框重现您的错误消息:

In [589]: df=pd.DataFrame(np.arange(12).reshape(6,2))
In [590]: df
Out[590]:
0 1
0 0 1
1 2 3
2 4 5
3 6 7
4 8 9
5 10 11

将系列放入 set 中是可行的,就像我们将列表放入 set 中一样:

In [591]: set(df[0]).union(set(df[1]))
Out[591]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}

但是,如果我尝试将包含系列的列表放入集合中,我会收到错误消息。

In [592]: set([df[0]])
....
TypeError: 'Series' objects are mutable, thus they cannot be hashed

如果问题不在于 set 表达式,那么问题就出现在 dict() 表达式中。

您没有指定错误发生的位置,也没有提供 MVCe。

(但事实证明这是一个死胡同)

==========================

好的,模拟您的代码:

In [606]: DC=dict.fromkeys(list(df.columns))
In [607]: DC
Out[607]: {0: None, 1: None}
In [608]: INN=list(df.columns)
In [609]: INN
Out[609]: [0, 1]
In [610]: for col in df:
...: dict(zip(INN, df.apply(jaccard_d, df[col])))
....
----> 2 dict(zip(INN, df.apply(jaccard_d, df[col])))


/usr/local/lib/python3.5/dist-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, args, **kwds)
...
-> 4125 axis = self._get_axis_number(axis)

/usr/local/lib/python3.5/dist-packages/pandas/core/generic.py in _get_axis_number(self, axis)
326
327 def _get_axis_number(self, axis):
--> 328 axis = self._AXIS_ALIASES.get(axis, axis)
....

TypeError: 'Series' objects are mutable, thus they cannot be hashed

所以问题出在

df.apply(jaccard_d, df[0])

该问题与jaccard_d无关。如果我用 simple 替换它就会发生

def foo(series1, series2):
print(series1)
print(series2)
return 1

======================

但是请查看apply的文档

df.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)

第二个参数(如果不是关键字)是轴编号。所以我们一直在尝试使用Series作为轴号!难怪会反对!如果我更仔细地阅读错误跟踪,那应该是显而易见的。

保留默认的axis=0,让其他系列作为args传递:

In [632]: df.apply(jaccard_d,args=(df[1],))
Out[632]:
0 0.0
1 1.0
dtype: float64

或者在你的循环中:

In [643]: for col in df:
...: DC[col] = dict(zip(INN, df.apply(jaccard_d,args=(df[col],))))
In [644]: DC
Out[644]: {0: {0: 1.0, 1: 0.0}, 1: {0: 0.0, 1: 1.0}}

关于python - 在 pandas 系列上使用 apply 方法获取 TypeError 'Series' 对象是可变的,因此无法对其进行哈希处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41926841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com