切片/分弦系列在不同位置

时间:2015-08-07 15:14:24

标签: python pandas

我希望根据某些子字符串的长度在不同点分割a string Series

In [47]: df = pd.DataFrame(['group9class1', 'group10class2', 'group11class20'], columns=['group_class'])
In [48]: split_locations = df.group_class.str.rfind('class')
In [49]: split_locations
Out[49]: 
0    6
1    7
2    7
dtype: int64
In [50]: df
Out[50]: 
      group_class
0    group9class1
1   group10class2
2  group11class20

我的输出应该如下:

      group_class    group    class
0    group9class1   group9   class1
1   group10class2  group10   class2
2  group11class20  group11  class20

我认为这可能有用:

In [56]: df.group_class.str[:split_locations]
Out[56]: 
0   NaN
1   NaN
2   NaN

如何根据split_locations中的变量位置剪切字符串?

3 个答案:

答案 0 :(得分:2)

这可行,通过使用双[[]],您可以访问当前元素的索引值,以便您可以索引到split_locations系列:

In [119]:    
df[['group_class']].apply(lambda x: pd.Series([x.str[split_locations[x.name]:][0], x.str[:split_locations[x.name]][0]]), axis=1)
Out[119]:
         0        1
0   class1   group9
1   class2  group10
2  class20  group11

或者@ajcr建议你可以extract

In [106]:

df['group_class'].str.extract(r'(?P<group>group[0-9]+)(?P<class>class[0-9]+)')
Out[106]:
     group    class
0   group9   class1
1  group10   class2
2  group11  class20

修改

正则表达式解释:

正则表达式来自@ajcr(谢谢!),这使用str.extract来提取组,这些组成为新列。

因此?P<group>标识要查找的特定组的ID,如果缺少该ID,则将为列名返回一个int。

所以其余部分应该是不言自明的:group[0-9]查找字符串group,后跟[0-9]范围内的数字,[]表示,这是相当于group\d,其中\d表示数字。

所以它可以重写为:

df['group_class'].str.extract(r'(?P<group>group\d+)(?P<class>class\d+)')

答案 1 :(得分:2)

使用正则表达式拆分字符串

 import re

 regex = re.compile("(class)")
 str="group1class23"
 # this will split the group and the class string by adding a space between them, and using a simple split on space.
 split_string = re.sub(regex, " \\1", str).split(" ")

这将返回数组:

 ['group9', 'class23']

因此,要向DataFrame添加两个新列,您可以执行以下操作:

new_cols = [re.sub(regex, " \\1", x).split(" ") for x in df.group_class]
df['group'], df['class'] = zip(*new_cols)

结果是:

      group_class    group    class
0    group9class1   group9   class1
1   group10class2  group10   class2
2  group11class20  group11  class20

答案 2 :(得分:2)

您还可以将zip与列表理解结合使用。

df['group'], df['class'] = zip(
    *[(string[:n], string[n:]) 
      for string, n in zip(df.group_class, split_locations)])

>>> df
      group_class    group    class
0    group9class1   group9   class1
1   group10class2  group10   class2
2  group11class20  group11  class20