代码之家  ›  专栏  ›  技术社区  ›  VERBOSE

如何将字符串(单列)转换为DataFrame?

  •  1
  • VERBOSE  · 技术社区  · 2 年前

    我的输入是一个字符串:

    text = '''10 February 2023
    abc
    def
    23 March 2023
    ghi
    jkl'''
    

    我制作了以下代码(使用regex,但我对任何其他选择都持开放态度):

    data = []
    
    for m in re.finditer(r'(\d+ \w+ \w+)\n(.*)', text, flags=re.I|re.S):
        data.append([m.group(1), m.group(2).splitlines()])
        
    df = pd.DataFrame(data, columns=['date', 'letters']).explode('letters')
    

    我的代码给出了一个奇怪的结果:

                   date        letters
    0  10 February 2023            abc
    0  10 February 2023            def
    0  10 February 2023  23 March 2023
    0  10 February 2023            ghi
    0  10 February 2023            jkl
    

    当我期待这个的时候:

                   date        letters
    0  10 February 2023            abc
    0  10 February 2023            def
    1     23 March 2023            ghi
    1     23 March 2023            jkl
    
    

    如何修复我的代码?此外,你有其他选择吗?我很有兴趣向他们学习。

    1 回复  |  直到 2 年前
        1
  •  2
  •   mozway    2 年前

    一个没有正则表达式的选项,利用日期识别 pd.to_datetime :

    df = pd.DataFrame({'letters': text.splitlines()})
    m = pd.to_datetime(df['letters'], errors='coerce').notna()
    
    out = df.assign(date=df['letters'].where(m).ffill()
                    ).loc[~m, ::-1].reset_index(drop=True)
    

    可选语法:

    s = pd.Series(text.splitlines())
    m = pd.to_datetime(s, errors='coerce').notna()
    
    df = pd.DataFrame({'date': s.where(m).ffill(), 'letters': s}
                      )[~m].reset_index(drop=True)
    

    输出:

                   date letters
    0  10 February 2023     abc
    1  10 February 2023     def
    2     23 March 2023     ghi
    3     23 March 2023     jkl