在字符串上切片和使用列表推导式时遇到困难

Struggling with slicing over strings and using list comprehension

提问人:Фома Ф 提问时间:9/23/2023 更新时间:9/24/2023 访问量:34

问:

我目前正在研究一个数据集中的熊猫数据帧,其中包括 2012 年以来进出德国的进出口收入。为了清楚起见,我想再添加一列“大陆”,并为每个国家分配其位置。我的数据帧是按国家和年份排序的。代码片段如下所示:

国家 法典 ... 大陆
阿富汗 ST423型 ... 4 <-- 期望的结果

“代码”中的第三个字符定义了大陆:1 代表欧洲,2 代表非洲,3 代表美洲,4 代表亚洲,5 代表大洋洲。我正在尝试用大陆名称填充“大陆”列。

我尝试的是首先创建一个系列“代码”的列表

codelist = df["Code"].to_list()

然后我尝试(在未能实现目标后)至少将数字添加到该列中,因此“代码”中每个值中的第三个符号。但即使在这里,我也没有这样做:

[codelist[x][2] for x in range(0,len(codelist)-1)]

它指出:“IndexError:字符串索引超出范围”,我不明白,因为

codelist[0][2] 

codelist[len(codelist)-1][2] 

两者都给出了积极的结果。

Python Pandas 列表-理解 切片

评论

0赞 Jacob H 9/23/2023
该错误表明“代码”列中某处的项不够长,因此超出了范围。 之所以有效,是因为 DataFrame 中的第一项没有这个问题,但似乎有一个项目在更远的地方存在。另外(与错误无关)我认为您不想从您的范围内减去 1。 不包括最后一个值,例如 给。[2]codelist[0][2] len(codelist)range(x, y)range(0, 3)[0, 1, 2]
0赞 Фома Ф 9/24/2023
谢谢,你是对的。我收到了错误;确实有两个字符的长条目,这就是它不起作用的原因。

答:

0赞 Timeless 9/24/2023 #1

因为该列肯定包含至少一个长度短于 3 的字符串。Code

       Country   Code
0  Afghanistan  ST423
1            A     ST
2            B   None
3            C    XXX

      1 codelist = df["Code"].to_list()
----> 2 [codelist[x][2] for x in range(0,len(codelist)-1)]

IndexError: string index out of range

你可以改用 str/map

d = dict(enumerate(["Europe", "Africa", "Americas", "Asia", "Oceania"], 1))

df["Continent"] = pd.to_numeric(df["Code"].str[2], errors="coerce").map(d)

另一个带有提取物的变体:

df["Continent"] = df["Code"].str.extract(
            "..(\d)", expand=False).astype("Int8").map(d)

或者,如果你更喜欢 listcomp,你可以通过添加一个语句来修复你的代码:if/else

df["Continent"] = [
    d.get(int(c[2])) if c and len(c)>2 and c[2].isdigit()
    else None for c in df["Code"] # <-- change None if needed
]

输出:

print(df)

       Country   Code Continent
0  Afghanistan  ST423      Asia
1            A     ST       NaN
2            B   None       NaN
3            C    XXX       NaN

使用的输入 :

df = pd.DataFrame(
    {'Country': ['Afghanistan', 'A', 'B', 'C'],
     'Code': ['ST423', 'ST', None, 'XXX']}
)
0赞 Mark Ransom 9/24/2023 #2

正如其他人所说,在某个地方,你的一个少于 3 个字符。如果您不介意为 Continent 设置一个空字符串,则很容易修复:Code

[codelist[x][2:3] for x in range(0,len(codelist)-1)]

切片是一件有趣的事情。如果请求一个不存在的索引,则会得到一个 .但是,如果你要求一个不存在的范围,你会得到一个空的结果。因此,只需使用长度为单个字符的范围即可。IndexError