求解, Panda 比较操作会在一个循环执行第二遍时会报错

2021-05-19 16:29:41 +08:00
 Wolfsin
    for j in range(1, 6):
        TestSet = GroupList[j - 1]
        TrainSet = GroupList.copy()
        TrainSet.remove(TestSet)

GroupList 里面存放的是结构相同的 Panda.DataFrame (仅数据不同),循环第一遍非常顺利,但是到了第二遍,会在 remove()操作这部报错:

ValueError: Can only compare identically-labeled DataFrame objects

因为用 PD 比较少,所以不太理解为什么会发生这种错误。 虽然可以改用 index 来 del(),但是还是想知道这样操作不行的理由。不知道有没有人遇到过。

629 次点击
所在节点    问与答
9 条回复
rationa1cuzz
2021-05-19 17:36:16 +08:00
data=DataFrame.copy(deep=False)
等价于
data=DataFrame
默认浅拷贝,你第一次给删了,肯定会出问题
Wolfsin
2021-05-19 17:49:50 +08:00
@rationa1cuzz #1
那个 GroupList 是一个 List,他的结构是

List = [DataFrame1,DataFrame2,DataFrame3,DataFrame4,DataFrame5]

list.copy(),虽然是浅拷贝,但是我断点下来的结果,第二次的 remove 前,list 跟第一次的 list 是一样的。

另外如果对 list,做深拷贝( copy.deepcopy )那么在第一次 remove 时就会报:

ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

错误
Wolfsin
2021-05-19 17:58:38 +08:00
@Wolfsin #2
哦,另外我知道 list.copy(),对于 list 嵌套 list 这种情况,只能实现第一层的深拷贝,但是我这边的结构应该已经完成了深拷贝了。而且按照逻辑上来,即使是因为拷贝的问题,每次 remove()的对象,是上一轮中并没有被移除出去,所以应该也不会报错(就算是真有问题,应该也不是报 DataFrame 的错,应该是报 ValueError: list.remove(x): x not in list )
toaruScar
2021-05-19 23:35:37 +08:00
Functional programming 不香吗?都不用考虑深浅复制的问题

for df in GroupList:
print(list(filterfalse(lambda x: x.equals(df),GroupList)))
toaruScar
2021-05-19 23:36:13 +08:00
Xs0ul
2021-05-20 02:54:17 +08:00
看起来是要自己写 CV ?不如考虑用 sklearn 里的 split ?
rationa1cuzz
2021-05-20 10:33:51 +08:00
不好意思之前没仔细看 ValueError: Can only compare identically-labeled DataFrame objects 看了一下这个报错应该是 GroupList 里的 TestSet 的 index 或者 columns 不一致导致的,第一遍顺利是因为行列一致,你可以打印看一下
详见 /Library/Python/3.8/lib/python/site-packages/pandas/core/generic.py 1305 行
另外 ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().这个报错估计是因为数据类型不一致导致的或者是 pandas 内部捕捉了直接 return,我本地 a=[df1,df2,df3] a.remove(df1)不报错 a.remove(df2)也会报错 ValueError,盲猜一个判断等于的时候报错 pandas 捕捉到了直接 return 了。具体你看看源码吧
Wolfsin
2021-05-20 20:07:52 +08:00
@Xs0ul #6 谢谢推荐,不用 sklearn 的 split 是因为数据集已经分好 group 了,为了保证结果的可比较性,所以按照说明 4group 为 train,1group 为 test 。而且还要考虑排列组合的问题,所以还是打算手写了。
@rationa1cuzz #7 感觉也是比较这边出的问题,不过最后偷懒用 index 移除了。而且这种方法好像还是速度还快一点。
Xs0ul
2021-05-20 22:00:59 +08:00
好像回晚了,已经定好 group 的话也可以看看:
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GroupKFold.html#sklearn.model_selection.GroupKFold

自己写的话,其实楼上用 filter 的可能比用 copy 和 pop 更好一点,或者直接更清晰一点写成类似:
TrainSet = [g for i, g in enumerate(GroupList) if i != j]

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/777937

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX