PySpark/Python3.6 'int'对象不可下标错误及RDD代码实现问题
嘿,我来帮你搞定这个PySpark里的TypeError: 'int' object is not subscriptable问题!
错误根源拆解
你代码里的核心问题是搞错了RDD元素的结构访问方式:
- RDD_one的每个元素是类似
(0, [(0, '5'), (1, '1'), (2, '2'), ...])的二元组,lambda里的x就是这个元组——x[0]是整数类型的主索引,x[1]才是包含(序号, 值)子元组的列表。 - 你写的
[list(x[i][1]) for i in range(n)]里,x[i]当i=0时取到的是x[0](也就是那个整数索引),接着再用[1]做下标访问,自然就触发了“int对象不能被下标”的错误。 - 另外,你代码末尾的
x[i+1][1]还有个隐藏问题:这里的i是列表推导式循环结束后的最后一个值(n=2时i=1),此时x[i+1]就是x[2],但x只有两个元素,还会引发索引越界错误。
贴合需求的修正方案
结合你描述的需求(生成元组(x, y, z),x是原索引,y是含n个元素的列表,z是列表的前一个元素值),分两种常见场景给你修正代码:
场景1:对每个原元素生成多个滑动窗口元组
如果你想遍历子列表中的连续n元素窗口,每个窗口对应一个输出元组(比如从第2个元素开始,每个窗口取前n个值,z是窗口的前一个元素值),用flatMap实现:
n = 2 RDD_Dados = RDD_one.flatMap(lambda x: [ (x[0], [sub[1] for sub in x[1][k:k+n]], x[1][k-1][1]) for k in range(1, len(x[1]) - n + 1) ])
代码说明
- 用
flatMap替代map:每个输入元素会生成多个输出元组,对应不同的窗口位置。 range(1, len(x[1]) - n + 1):保证窗口不会越界,同时k-1是有效的索引(避免取到不存在的元素)。[sub[1] for sub in x[1][k:k+n]]:正确从子列表x[1]中截取n个元素,提取它们的value组成y。x[1][k-1][1]:准确获取窗口前一个元素的value,也就是你要的z。
场景2:对每个原元素生成单个元组
如果你只是想取子列表的前n个元素作为y,取前n个元素的最后一个值(或指定的“前一个”值)作为z,用map实现:
n = 2 RDD_Dados = RDD_one.map(lambda x: ( x[0], [sub[1] for sub in x[1][:n]], # 取子列表前n个元素的value组成y x[1][n-1][1] if len(x[1]) >= n else None # 取前n个元素的最后一个值作为z,同时处理子列表长度不足的情况 ))
测试示例
用你给出的RDD_one元素(0, [(0, '5'), (1, '1'), (2, '2'), (3, '4'), ...])测试场景1的代码,会生成如下部分结果:
(0, ['1', '2'], '5')(窗口是第1-2个元素,前一个值是第0个元素的'5')(0, ['2', '4'], '1')(窗口是第2-3个元素,前一个值是第1个元素的'1')
这样就完全解决了之前的TypeError问题,也完美贴合你的需求~
内容的提问来源于stack exchange,提问作者Pablo Luiz Leon
相关产品推荐
相关产品推荐

