使用正则表达式根据列的值在数据集中创建新列

Posted

技术标签:

【中文标题】使用正则表达式根据列的值在数据集中创建新列【英文标题】:creating new columns in a data set based on values of a column using Regex 【发布时间】:2017-12-01 20:57:40 【问题描述】:

这是我的数据框

index     duration 
1           7 year   
2           2day
3           4 week
4           8 month

我需要将数字与时间分开并将它们放在两个新列中。输出是这样的:

index     duration         number     time
1           7 year          7         year
2           2day            2         day
3           4 week          4        week
4           8 month         8         month

这是我的代码:

df ['numer'] = df.duration.replace(r'\d.*' , r'\d', regex=True, inplace = True)
df [ 'time']= df.duration.replace (r'\.w.+',r'\w.+', regex=True, inplace = True )

但它不起作用。有什么建议吗?

我还需要根据时间列的值创建另一列。所以新的数据集是这样的:

 index     duration         number     time      time_days
    1           7 year          7         year       365
    2           2day            2         day         1
    3           4 week          4        week         7
    4           8 month         8         month       30

df['time_day']= df.time.replace(r'(year|month|week|day)', r'(365|30|7|1)', regex=True, inplace=True)

有什么建议吗?

【问题讨论】:

你的最终目标是什么?你将如何使用这些解析的列? 【参考方案1】:

我们可以在这里使用Series.str.extract:

In [67]: df[['number','time']] = df.duration.str.extract(r'(\d+)\s*(.*)', expand=True)

In [68]: df
Out[68]:
   index duration number    time
0      1   7 year      7    year
1      2     2day      2     day
2      3   4 week      4    week
3      4  8 month      8   month

RegEx explained - regex101.com 是 IMO 最好的在线 RegEx 解析器、测试器和解释器之一

您可能还想将 number 列转换为整数 dtype:

In [69]: df['number'] = df['number'].astype(int)

In [70]: df.dtypes
Out[70]:
index        int64
duration    object
number       int32
time        object
dtype: object

更新:

In [167]: df['time_day'] = df['time'].replace(['year','month','week','day'], [365, 30, 7, 1], regex=True)

In [168]: df
Out[168]:
   index duration number    time  time_day
0      1   7 year      7    year       365
1      2     2day      2     day         1
2      3   4 week      4    week         7
3      4  8 month      8   month        30

【讨论】:

您能解释一下这段代码 df.duration.str.extract(r'(\d+)\s*?(.*)$', expand=True) 的工作原理吗?我不明白?和 $ 在这里。 @Mary,我稍微优化了 RegEx 并添加了一个指向解释过的 RegEx 的链接 - 请检查【参考方案2】:

您可以将str.extractastype 一起使用:

df = df['duration'].str.extract(r'(?P<number>\d+)\s*(?P<time>\w+)', expand=True)
#convert to int
df['number'] = df['number'].astype(int)
print (df)
   number   time
0       7   year
1       2    day
2       4   week
3       8  month

Extracting substrings.

用于添加到原始DataFrame

df = df.join(df['duration'].str.extract(r'(?P<number>\d+)\s*(?P<time>\w+)', expand=True))
#convert to int
df['number'] = df['number'].astype(int)
print (df)
   index duration  number   time
0      1   7 year       7   year
1      2     2day       2    day
2      3   4 week       4   week
3      4  8 month       8  month

df[['number','time']] = df['duration'].str.extract(r'(\d+)\s*(\w+)', expand=True)
#convert to int
df['number'] = df['number'].astype(int)
print (df)
   index duration  number   time
0      1   7 year       7   year
1      2     2day       2    day
2      3   4 week       4   week
3      4  8 month       8  month

【讨论】:

抱歉,我现在只接电话。所以我更喜欢字典的地图。 d = 'year':365, 'month':30, 'week':7, 'day':1 df['time_day'] = df['time'].map(d)。如果在time 列中只有 4 个可能的值,它就可以完美运行,否则会得到 NaN。如果需要更改不是所有值,而只更改一些值,则使用替换。所以这里有更好的地图。但是如果列中的值是 a, b, c,d, e,f... 并且只需要将 a,c 更改为 b,d 更好的解决方案是替换。祝你好运!

以上是关于使用正则表达式根据列的值在数据集中创建新列的主要内容,如果未能解决你的问题,请参考以下文章

Python使用提取的正则表达式创建一个新列,直到 \n 从数据框中

使用熊猫根据正则表达式分离列数据

迭代数据框并根据一列的值在具有前一行值的新列中执行操作

根据其他列中的值在 python 3 (pandas) 数据框中创建新列

带有熊猫列的正则表达式

如何删除 - 从右到左读取字符串值时