Pandas的str.split()函数无法正常工作

3

当我尝试使用Pandas系列str.split()函数分割数据帧中“Actors”列的值时,我得到的值比我指定的拆分数量要多:

df['Actors'] = df['Actors'].str.split(",",n=3)

1      [timrobbins, morganfreeman, bobgunton, william...
2      [marlonbrando, alpacino, jamescaan, richardsca...
3      [alpacino, robertduvall, dianekeaton, robertde...
4      [christianbale, heathledger, aaroneckhart, mic...
5      [martinbalsam, johnfiedler, leejcobb, egmarshall]

如果我使用下面的代码来切片上面的结果,那么结果中将出现NaN:
df['Actors'] = df['Actors'].str.split(",",n=3)[:3]
df['Actors'].head()

1    [timrobbins, morganfreeman, bobgunton, william...
2    [marlonbrando, alpacino, jamescaan, richardsca...
3    [alpacino, robertduvall, dianekeaton, robertde...
4                                                  NaN
5                                                  NaN
Name: Actors, dtype: object

如果我尝试使用下面显示的apply函数来运行代码片段,就可以得到正确的结果:

df['Actors'] = df['Actors'].apply(lambda x: x.split(",")[:3])
df['Actors'].head()

1        [timrobbins, morganfreeman, bobgunton]
2           [marlonbrando, alpacino, jamescaan]
3         [alpacino, robertduvall, dianekeaton]
4    [christianbale, heathledger, aaroneckhart]
5         [martinbalsam, johnfiedler, leejcobb]
Name: Actors, dtype: object

我想知道为什么会出现这样的异常情况以及如何在这种情况下正确使用str.split()函数?
要进一步检查数据,您可以使用以下代码片段自行下载数据:
df = pd.read_csv('https://query.data.world/s/uikepcpffyo2nhig52xxeevdialfl7',index_col=0)

你没有获得比你指定的更多的值。只是很难确定,因为逗号是值之间的分隔符,并且在原始数据中也是如此,而且它不会在字符串周围显示引号。你获得了 ["timrobbins", "morganfreeman", "bobgunton, william..."] - Barmar
请尝试使用以下代码在您的Jupyter笔记本或i-Python shell中下载数据:df = pd.read_csv('https://query.data.world/s/uikepcpffyo2nhig52xxeevdialfl7',index_col=0) df['Actors'] = df['Actors'].str.strip().str.lower().str.replace("[^a-zA-Z,]","") df['Actors'] = df['Actors'].str.split(", ",n=3) df['Actors'].head()。这将使您更好地了解数据。 - Sarvagya Dubey
我不使用Jupyter或I-Python。 - Barmar
你有任何可用的样本数据吗? - gosuto
问题在于 n=3 并不意味着丢弃第三个项目后的所有内容。它意味着所有项目都被包含为第三个值的一部分。 - Barmar
显示剩余3条评论
3个回答

3

据我所知,您现在想知道str.split(",",n=3)[:3]str.split(",").str[:3]之间的区别。

str.split(",",n=3)[:3]是在左到右将字符串以','为分隔符拆分三次。拆分后的输出是一个序列,其中每一行都是一个列表。接下来,在输出上调用[:3]。它切片输出的前三行并返回新的只有三行的序列。

df['Actors'] = df['Actors'].str.split(",",n=3)[:3]是序列赋值。序列赋值与索引对齐。任何df['Actors'].index不存在于输出的三行序列中的值将被赋为NaN。这就是为什么最终的df['Actors']只有三行具有值,其余为NaN的原因。

df['Actors'].str.split(",").str[:3]是Pandas的.str索引功能。它是Pandas str访问器的内置特性。它通过传递给[]的数字在每一行上切片整个序列。您可以在这里阅读更多: https://pandas.pydata.org/pandas-docs/stable/user_guide/text.html#indexing-with-str。它返回与原始序列相同长度(相同行数)的序列,其中每一行的值都被[]内的数字切片。


2

我刚刚找到了一种方法来完成这个任务。目前我还没有解释它的原理。也许你们可以帮我解释一下,但是这段代码确实有效:

df['Actors'] = df['Actors'].str.split(",").str[:3]
df['Actors'].head()

1        [timrobbins, morganfreeman, bobgunton]
2        [marlonbrando, alpacino, jamescaan]
3        [alpacino, robertduvall, dianekeaton]
4        [christianbale, heathledger, aaroneckhart]
5        [martinbalsam, johnfiedler, leejcobb]
Name: Actors, dtype: object

@jorijnsmit 非常感谢您的帮助。 - Sarvagya Dubey
什么难以解释?您可以将actors字符串进行拆分,然后使用切片获取前3个,这就是您想要的。 - Barmar
你可以使用 n=4,这样它就不会浪费时间分割你不感兴趣的剩余名称。 - Barmar
好的,让我告诉你这个很难理解的地方:str.split(",", 3) 会返回什么?可能是一个列表吧?然后在那个列表上,你怎么能够使用 .str 访问器,再切片 [0:3] 呢? - Sarvagya Dubey
它不会返回一个列表。这些东西都是Pandas Series。 - Barmar
这个问题和答案对我帮助很大。谢谢。 - zelfde

1
你所做的是对 Series 进行切片,而不是对字符串进行切片。这就是为什么从第四行开始你会得到 NaN。尝试使用 [:2],你将从第三行开始得到 NaN
使用 .apply(lambda x: x[:n]) 可以对实际的字符串进行切片。
或者,如果你不想使用 .apply(),可以对每一行的内容进行切片,而不是对整个系列进行切片:
df['Actors'] = df['Actors'].str.split(",").str[:3]

你提到的上面那段代码片段不是正确的方式,我只是试着对其进行了微调。实际的代码片段:df['Actors'] = df['Actors'].str.split(",",n=3),应该将'Actors'列中的字符串拆分为一个包含3个字符串元素的列表,但这并没有发生。请问你能帮我解决这个问题吗? - Sarvagya Dubey
我意外地找到了答案,请帮我解释一下。 - Sarvagya Dubey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接