用“_”拆分字符串列,删除前面的文本,在 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
根据数据的大小,您可以对这些方法进行基准测试并使用合适的方法。
>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
根据数据的大小,您可以对这些方法进行基准测试并使用合适的方法。