用“_”拆分字符串列,删除前面的文本,在 pandas 中用“_”重新组合 str

split string column by "_", drop the preceding text, recombine str by "_" in pandas

>e = {0: pd.Series(['NHL_toronto_maple-leafs_Canada', 'NHL_boston_bruins_US', 'NHL_detroit_red-wings', 'NHL_montreal'])}

>df = pd.DataFrame(e)

>df

    0
0   NHL_toronto_maple-leafs_Canada
1   NHL_boston_bruins_US
2   NHL_detroit_red-wings
3   NHL_montreal

我想:

1) 将上面的数据帧(系列)拆分为'_'

2) 删除 'NHL' 字符串

3) 通过'_'重新组合剩余的文本

4) 将#3 中的结果附加到原始数据框作为第二列

为此,我尝试了以下操作:

>df2 = df.icol(0).str.split('_').apply(pd.Series).iloc[:,1:]

>df2

    1   2   3
0   toronto maple-leafs Canada
1   boston  bruins  US
2   detroit red-wings   NaN
3   montreal    NaN NaN

我尝试按照 combine columns in Pandas 中的建议进行以下操作:

>df2['4'] = df2.iloc[:,0] + "_" + df2.iloc[:,1] + "_" + df2.iloc[:,2]

>df2

    1   2   3   4
0   toronto maple-leafs Canada  toronto_maple-leafs_Canada
1   boston  bruins  US  boston_bruins_US
2   detroit red-wings   NaN NaN
3   montreal    NaN NaN NaN

但是,您可以看到,在组合涉及 NaN 单元格的情况下,最终结果也是 NaN。这不是我想要的。

第 4 列应如下所示:

toronto_maple-leafs_Canada
boston_bruins_US
detroit_red-wings_US
montreal

由于我的真实数据集非常大,还有没有一种有效的方法来执行此类操作。

您可以像这样使用 apply

In [1782]: df[0].apply(lambda v: '_'.join(v.split('_')[1:]))
Out[1782]: 
0    toronto_maple-leafs_Canada
1              boston_bruins_US
2             detroit_red-wings
3                      montreal
Name: 0, dtype: object

In [1783]: df[0] = df[0].apply(lambda v: '_'.join(v.split('_')[1:]))

令人惊讶的是,应用 str 似乎比 apply 花费的时间更长:

In [1811]: %timeit df[0].apply(lambda v: '_'.join(v.split('_')[1:]))
10000 loops, best of 3: 127 µs per loop

In [1810]: %timeit df[0].str[4:]
1000 loops, best of 3: 179 µs per loop

In [1812]: %timeit df[0].str.split('_').str[1:].str.join('_')
1000 loops, best of 3: 553 µs per loop

In [1813]: %timeit df[0].str.split("_", 1).str[1]
1000 loops, best of 3: 374 µs per loop

如果您只是想删除起始 'NHL_' 子字符串,您可以

In [84]: df[0].str[4:]
Out[84]:
0    toronto_maple-leafs_Canada
1              boston_bruins_US
2             detroit_red-wings
3                      montreal
Name: 0, dtype: object

但是,如果您需要拆分和加入,您可以使用string method like-

In [85]: df[0].str.split('_').str[1:].str.join('_')
Out[85]:
0    toronto_maple-leafs_Canada
1              boston_bruins_US
2             detroit_red-wings
3                      montreal
Name: 0, dtype: object

或者,您也可以使用 apply

In [86]: df[0].apply(lambda x: '_'.join(x.split('_')[1:])) # Also, x.split('_', 1)[1]
Out[86]:
0    toronto_maple-leafs_Canada
1              boston_bruins_US
2             detroit_red-wings
3                      montreal
Name: 0, dtype: object

并且,正如@DSM 指出的那样 - "split 接受最大拆分数的参数"

In [87]: df[0].str.split("_", 1).str[1]
Out[87]:
0    toronto_maple-leafs_Canada
1              boston_bruins_US
2             detroit_red-wings
3                      montreal
Name: 0, dtype: object

根据数据的大小,您可以对这些方法进行基准测试并使用合适的方法。