如何在 Pandas DataFrame 中将可变大小的基于字符串的列拆分为多列?

sar*_*sky 5 python dataframe pandas

我有一个 Pandas DataFrame,其形式如下:

A      B       C     D
A1     6       7.5   NaN
A1     4       23.8  <D1 0.0 6.5 12 4, D2 1.0 4 3.5 1>
A2     7       11.9  <D1 2.0 7.5 10 2, D3 7.5 4.2 13.5 4> 
A3    11       0.8   <D2 2.0 7.5 10 2, D3 7.5 4.2 13.5 4, D4 2.0 7.5 10 2, D5 7.5 4.2 13.5 4>
Run Code Online (Sandbox Code Playgroud)

D列是一个原始字符串列,每个条目中有多个类别。条目的值是通过将每个类别的最后两个值相除来计算的。例如,在第二行:

D1 = 12/4 = 3
D2 = 3.5/1 = 3.5
Run Code Online (Sandbox Code Playgroud)

我需要根据它的类别拆分D列并将它们加入我的 DataFrame。问题是该列是动态的,在一个条目中可以有近 35-40 个类别。目前,我所做的只是迭代所有行的蛮力方法,这对于大型数据集来说非常慢。有人可以帮帮我吗?

预期结果

A      B       C     D1  D2  D3  D4  D5
A1     6       7.5   NaN NaN NaN NaN NaN
A1     4       23.8  3.0 3.5 NaN NaN NaN
A2     7       11.9  5.0 NaN 3.4 NaN NaN 
A3    11       0.8   NaN 5.0 3.4 5.0 3.4
Run Code Online (Sandbox Code Playgroud)

Shu*_*rma 3

使用:

d = df['D'].str.extractall(r'(D\d+).*?([\d.]+)\s([\d.]+)(?:,|\>)')
d = d.droplevel(1).set_index(0, append=True).astype(float)
d = df.join(d[1].div(d[2]).round(1).unstack()).drop('D', 1)
Run Code Online (Sandbox Code Playgroud)

细节:

用于按照模式指定的方式Series.str.extractall从列中提取所有捕获组。您可以测试该模式。Dregexregexhere

print(d)
          0     1  2 # --> capture groups
  match             
1 0      D1    12  4
  1      D2   3.5  1
2 0      D1    10  2
  1      D3  13.5  4
3 0      D2    10  2
  1      D3  13.5  4
  2      D4    10  2
  3      D5  13.5  4
Run Code Online (Sandbox Code Playgroud)

使用带有可选参数的DataFrame.droplevel+来删除未使用的级别并将新索引附加到 datafarme。set_indexappend=True

print(d)
         1    2
  0            
1 D1  12.0  4.0
  D2   3.5  1.0
2 D1  10.0  2.0
  D3  13.5  4.0
3 D2  10.0  2.0
  D3  13.5  4.0
  D4  10.0  2.0
  D5  13.5  4.0
Run Code Online (Sandbox Code Playgroud)

用于Series.div除以列12用于Series.round舍入值,然后用于Series.unstack重塑数据框,然后使用DataFrame.join连接新数据框df

print(d)
    A   B     C   D1   D2   D3   D4   D5
0  A1   6   7.5  NaN  NaN  NaN  NaN  NaN
1  A1   4  23.8  3.0  3.5  NaN  NaN  NaN
2  A2   7  11.9  5.0  NaN  3.4  NaN  NaN
3  A3  11   0.8  NaN  5.0  3.4  5.0  3.4
Run Code Online (Sandbox Code Playgroud)