pandas str.extract带有额外的逻辑(lambda?)

时间:2018-02-18 15:11:02

标签: python pandas

我在文中有很多类型的日期:

  • 2009年4月20日;
  • 09年4月20日;
  • 零九年四月二十零日;
  • 09年4月3日
  • 2009年4月20日;

还有更多。

我正在使用RegEx(或多个RegEx' s)来提取日期。

幸运的熊猫有一个非常有用的功能叫做提取物,例如这可以很好地提取我的大部分日期:

df['text'].str.extract(r'(\d{1,2})[\/-](\d{1,2})[\/-](\d{1,4})', expand=True)

如上所示,我有3个捕获组。这会创建3列:月,日,年。

是否有可能以某种方式在它们上运行lambda并创建一个列?

与使用lambdas的方式相同"替换"

df['text'].str.replace(r'(\w+day\b)', lambda x: x.groups()[0][:3])

2 个答案:

答案 0 :(得分:2)

通过调整正则表达式以使用一个捕获组,可以避免单独列的问题。这样的东西适用于你提供的日期格式:

df.date.str.extract(r'([0-9]{1,2}[\/\.\-][0-9]{1,2}[\/\.\-][0-9]{1,4})', expand=False)

您可以将结果进一步转换为datetime:

df['my_date_col'] = pd.to_datetime(df['my_date_col'])

证明pd.to_datetime宽松:

import pandas as pd

lst = ['04/03/2009', '04/03/09', '4/03/09', '4/3/09', '04-03-2009',
       '4-3-09', '3 Apr 2009', '3rd April 2009', '3-Apr-09', '3-Apr-2009',
       '04/3/09', '04-3-09', '04-3-2009', '4-03-2009']

set(map(pd.to_datetime, lst))

# {Timestamp('2009-04-03 00:00:00')}

答案 1 :(得分:1)

pandas.DatFrame.str.extract()的输出是一个数据帧。如果需要,您可以使用pandas.DataFrame.apply(),如:

代码:

dates = df['text'].str.extract(extract_re, expand=True).apply(
    lambda row: row.str.cat(sep='/'), axis=1)

测试代码:

df = pd.DataFrame("""
    04/20/2009;
    04/20/09;
    4/20/09;
    4/3/09
    04-20-2009;
""".split('\n')[1:-1], columns=['text'])
print(df)

extract_re = r'(\d{1,2})[\/-](\d{1,2})[\/-](\d{1,4})'
dates = df['text'].str.extract(extract_re, expand=True).apply(
    lambda row: row.str.cat(sep='/'), axis=1)
print(dates)

结果:

              text
0      04/20/2009;
1        04/20/09;
2         4/20/09;
3           4/3/09
4      04-20-2009;

0    04/20/2009
1      04/20/09
2       4/20/09
3        4/3/09
4    04/20/2009
dtype: object