多部分操作 post str.split() Pandas

Multi-part manipulation post str.split() Pandas

我有一个数据子集(单列),我们称之为 ID:

    ID
0   07-1401469
1   07-89556629
2   07-12187595
3   07-381962
4   07-99999085

当前格式是(通常)YY-[最多 8 个字符的 ID]。 期望的输出格式是更统一的 YYYY-xxxxxxxx:

    ID
0   2007-01401469
1   2007-89556629
2   2007-12187595
3   2007-00381962
4   2007-99999085

知道以前做过padding,思路就是结合

df['id'].str.split('-').str[0].apply(lambda x: '{0:20>4}'.format(x))
df['id'].str.split('-').str[1].apply(lambda x: '{0:0>8}'.format(x))

不过我运行遇到了几个问题:

  1. “{0:20>4}”中的“20”必须是单数而不是字符串
  2. 尝试执行类似下面的操作只会导致 df['id'] 获取最后一个 lambda 的属性并尝试以任何其他方式组合多个 apply/lambdas 只是行不通。我开始沿着垫 left/right 路线走,但那似乎是倒退的。
df['id'] = (df['id'].str.split('-').str[0].apply(lambda x: '{0:X>4}'.format(x)).str[1].apply(lambda x: '{0:0>8}'.format(x)))

我目前的解决方案(但讨厌,因为它又长又乱,而且在我看来不干净)是:

df['idyear'] = df['id'].str.split('-').str[0].apply(lambda x: '{:X>4}'.format(x)) # Split on '-' and pad with X
df['idyear'] = df['idyear'].str.replace('XX', '20') # Replace XX with 20 to conform to YYYY
df['idnum'] = df['id'].str.split('-').str[1].apply(lambda x: '{0:0>8}'.format(x)) # Pad 0s up to 8 digits
df['id'] = df['idyear'].map(str) + "-" + df['idnum'] # Merge idyear and idnum to remake id
del df['idnum'] # delete extra
del df['idyear'] # delete extra

哪个有效

      ID
0     2007-01401469
1     2007-89556629
2     2007-12187595
3     2007-00381962
4     2007-99999085

但我的问题是

  1. 有没有办法在一行中 运行 多个 apply() 函数,这样我就不会创建临时变量
  2. 有没有比用 'XX' 替换 '20'
  3. 更好的方法

我觉得整个代码块可以压缩到 1 或 2 行,我只是不知道如何压缩。到目前为止,我在 SO 和 Pandas 上看到的关于 highlights/relates 到单一操作的所有内容。

一个选择是拆分;然后使用 str.zfill 填充 '0's。还要在拆分前添加 '20's,因为无论如何你似乎都需要它:

tmp = df['ID'].radd('20').str.split('-')
df['ID'] = tmp.str[0] + '-'+ tmp.str[1].str.zfill(8)

输出:

              ID
0  2007-01401469
1  2007-89556629
2  2007-12187595
3  2007-00381962
4  2007-99999085

我会分两步完成,使用 .str.replace:

df["ID"] = df["ID"].str.replace(r"^(\d{2})-", r"20-", regex=True)
df["ID"] = df["ID"].str.replace(r"-(\d+)", lambda g: f"-{g[1]:0>8}", regex=True)
print(df)

打印:

              ID
0  2007-01401469
1  2007-89556629
2  2007-12187595
3  2007-00381962
4  2007-99999085