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(),但是还是想知道这样操作不行的理由。不知道有没有人遇到过。
根据 rationa1cuzz 的实验,猜测是pd本身不支持从list[df1.df2]这种结构从比较df? 因为着急写脚本就没有继续深挖这个问题了,最后这个需求是用以下方式解决的。
for j in range(1, 6):
TestSet = GroupList[j - 1]
TrainSet = GroupList.copy()
TrainSet.pop(j)
1
rationa1cuzz 2021-05-19 17:36:16 +08:00
data=DataFrame.copy(deep=False)
等价于 data=DataFrame 默认浅拷贝,你第一次给删了,肯定会出问题 |
2
Wolfsin OP @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(). 错误 |
3
Wolfsin OP @Wolfsin #2
哦,另外我知道 list.copy(),对于 list 嵌套 list 这种情况,只能实现第一层的深拷贝,但是我这边的结构应该已经完成了深拷贝了。而且按照逻辑上来,即使是因为拷贝的问题,每次 remove()的对象,是上一轮中并没有被移除出去,所以应该也不会报错(就算是真有问题,应该也不是报 DataFrame 的错,应该是报 ValueError: list.remove(x): x not in list ) |
4
toaruScar 2021-05-19 23:35:37 +08:00
Functional programming 不香吗?都不用考虑深浅复制的问题
for df in GroupList: print(list(filterfalse(lambda x: x.equals(df),GroupList))) |
5
toaruScar 2021-05-19 23:36:13 +08:00
|
6
Xs0ul 2021-05-20 02:54:17 +08:00 1
看起来是要自己写 CV ?不如考虑用 sklearn 里的 split ?
|
7
rationa1cuzz 2021-05-20 10:33:51 +08:00 1
不好意思之前没仔细看 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 了。具体你看看源码吧 |
8
Wolfsin OP @Xs0ul #6 谢谢推荐,不用 sklearn 的 split 是因为数据集已经分好 group 了,为了保证结果的可比较性,所以按照说明 4group 为 train,1group 为 test 。而且还要考虑排列组合的问题,所以还是打算手写了。
@rationa1cuzz #7 感觉也是比较这边出的问题,不过最后偷懒用 index 移除了。而且这种方法好像还是速度还快一点。 |
9
Xs0ul 2021-05-20 22:00:59 +08:00 1
好像回晚了,已经定好 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] |